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:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2008-08-13 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:56 +0300
commit173c07e166fdf6fcd20f18ea73008f1b628945df (patch)
tree13ebea85cdc4c16ae93714ff0627ee9f91ad7e08 /CPP/7zip/Archive/7z/7zHandlerOut.cpp
parent3901bf0ab88106a5b031cba7bc18d60cdebf7eef (diff)
4.59 beta
Diffstat (limited to 'CPP/7zip/Archive/7z/7zHandlerOut.cpp')
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandlerOut.cpp207
1 files changed, 110 insertions, 97 deletions
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index af4b9427..ac9ef987 100755
--- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -163,7 +163,7 @@ HRESULT CHandler::SetCompressionMethod(
for (int j = 0; j < methodFull.Properties.Size(); j++)
{
const CProp &prop = methodFull.Properties[j];
- if ((prop.Id == NCoderPropID::kDictionarySize ||
+ if ((prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
{
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
@@ -185,17 +185,20 @@ HRESULT CHandler::SetCompressionMethod(
return S_OK;
}
-static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)
{
- filetimeIsDefined = false;
- NCOM::CPropVariant propVariant;
- RINOK(updateCallback->GetProperty(index, propID, &propVariant));
- if (propVariant.vt == VT_FILETIME)
+ ft = 0;
+ ftDefined = false;
+ if (!writeTime)
+ return S_OK;
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_FILETIME)
{
- filetime = propVariant.filetime;
- filetimeIsDefined = true;
+ ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
+ ftDefined = true;
}
- else if (propVariant.vt != VT_EMPTY)
+ else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
return S_OK;
}
@@ -205,7 +208,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
COM_TRY_BEGIN
- const CArchiveDatabaseEx *database = 0;
+ const CArchiveDatabaseEx *db = 0;
#ifdef _7Z_VOL
if(_volumes.Size() > 1)
return E_FAIL;
@@ -213,139 +216,131 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_volumes.Size() == 1)
{
volume = &_volumes.Front();
- database = &volume->Database;
+ db = &volume->Database;
}
#else
if (_inStream != 0)
- database = &_database;
+ db = &_db;
#endif
- // CRecordVector<bool> compressStatuses;
CObjectVector<CUpdateItem> updateItems;
- // CRecordVector<UInt32> copyIndices;
- // CMyComPtr<IUpdateCallback2> updateCallback2;
- // updateCallback->QueryInterface(&updateCallback2);
-
- for(UInt32 i = 0; i < numItems; i++)
+ for (UInt32 i = 0; i < numItems; i++)
{
Int32 newData;
Int32 newProperties;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
- RINOK(updateCallback->GetUpdateItemInfo(i,
- &newData, &newProperties, &indexInArchive));
- CUpdateItem updateItem;
- updateItem.NewProperties = IntToBool(newProperties);
- updateItem.NewData = IntToBool(newData);
- updateItem.IndexInArchive = indexInArchive;
- updateItem.IndexInClient = i;
- updateItem.IsAnti = false;
- updateItem.Size = 0;
-
- if (updateItem.IndexInArchive != -1)
+ RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive));
+ CUpdateItem ui;
+ ui.NewProperties = IntToBool(newProperties);
+ ui.NewData = IntToBool(newData);
+ ui.IndexInArchive = indexInArchive;
+ ui.IndexInClient = i;
+ ui.IsAnti = false;
+ ui.Size = 0;
+
+ if (ui.IndexInArchive != -1)
{
- const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
- updateItem.Name = fileItem.Name;
- updateItem.IsDirectory = fileItem.IsDirectory;
- updateItem.Size = fileItem.UnPackSize;
- updateItem.IsAnti = fileItem.IsAnti;
+ const CFileItem &fi = db->Files[ui.IndexInArchive];
+ ui.Name = fi.Name;
+ ui.IsDir = fi.IsDir;
+ ui.Size = fi.Size;
+ ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
- updateItem.CreationTime = fileItem.CreationTime;
- updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
- updateItem.LastWriteTime = fileItem.LastWriteTime;
- updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
- updateItem.LastAccessTime = fileItem.LastAccessTime;
- updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
+ ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
+ ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
+ ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
}
- if (updateItem.NewProperties)
+ if (ui.NewProperties)
{
bool nameIsDefined;
bool folderStatusIsDefined;
{
- NCOM::CPropVariant propVariant;
- RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
- if (propVariant.vt == VT_EMPTY)
- updateItem.AttributesAreDefined = false;
- else if (propVariant.vt != VT_UI4)
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
+ if (prop.vt == VT_EMPTY)
+ ui.AttribDefined = false;
+ else if (prop.vt != VT_UI4)
return E_INVALIDARG;
else
{
- updateItem.Attributes = propVariant.ulVal;
- updateItem.AttributesAreDefined = true;
+ ui.Attrib = prop.ulVal;
+ ui.AttribDefined = true;
}
}
- RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
- RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
- RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
+ // we need MTime to sort files.
+ RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));
+ RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));
+ RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined));
{
- NCOM::CPropVariant propVariant;
- RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
- if (propVariant.vt == VT_EMPTY)
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
+ if (prop.vt == VT_EMPTY)
nameIsDefined = false;
- else if (propVariant.vt != VT_BSTR)
+ else if (prop.vt != VT_BSTR)
return E_INVALIDARG;
else
{
- updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
+ ui.Name = NItemName::MakeLegalName(prop.bstrVal);
nameIsDefined = true;
}
}
{
- NCOM::CPropVariant propVariant;
- RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
- if (propVariant.vt == VT_EMPTY)
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
+ if (prop.vt == VT_EMPTY)
folderStatusIsDefined = false;
- else if (propVariant.vt != VT_BOOL)
+ else if (prop.vt != VT_BOOL)
return E_INVALIDARG;
else
{
- updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ ui.IsDir = (prop.boolVal != VARIANT_FALSE);
folderStatusIsDefined = true;
}
}
{
- NCOM::CPropVariant propVariant;
- RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
- if (propVariant.vt == VT_EMPTY)
- updateItem.IsAnti = false;
- else if (propVariant.vt != VT_BOOL)
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
+ if (prop.vt == VT_EMPTY)
+ ui.IsAnti = false;
+ else if (prop.vt != VT_BOOL)
return E_INVALIDARG;
else
- updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
+ ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
}
- if (updateItem.IsAnti)
+ if (ui.IsAnti)
{
- updateItem.AttributesAreDefined = false;
+ ui.AttribDefined = false;
- updateItem.IsCreationTimeDefined = false;
- updateItem.IsLastWriteTimeDefined = false;
- updateItem.IsLastAccessTimeDefined = false;
+ ui.CTimeDefined = false;
+ ui.ATimeDefined = false;
+ ui.MTimeDefined = false;
- updateItem.Size = 0;
+ ui.Size = 0;
}
- if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
- updateItem.SetDirectoryStatusFromAttributes();
+ if (!folderStatusIsDefined && ui.AttribDefined)
+ ui.SetDirStatusFromAttrib();
}
- if (updateItem.NewData)
+ if (ui.NewData)
{
- NCOM::CPropVariant propVariant;
- RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
- if (propVariant.vt != VT_UI8)
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
+ if (prop.vt != VT_UI8)
return E_INVALIDARG;
- updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
- if (updateItem.Size != 0 && updateItem.IsAnti)
+ ui.Size = (UInt64)prop.uhVal.QuadPart;
+ if (ui.Size != 0 && ui.IsAnti)
return E_INVALIDARG;
}
- updateItems.Add(updateItem);
+ updateItems.Add(ui);
}
CCompressionMethodMode methodMode, headerMethod;
@@ -359,10 +354,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool compressMainHeader = _compressHeaders; // check it
+ bool encryptHeaders = false;
+
if (methodMode.PasswordIsDefined)
{
- compressMainHeader = true;
- if(_encryptHeaders)
+ if (_encryptHeadersSpecified)
+ encryptHeaders = _encryptHeaders;
+ #ifndef _NO_CRYPTO
+ else
+ encryptHeaders = _passwordIsDefined;
+ #endif
+ compressMainHeader = true;
+ if(encryptHeaders)
RINOK(SetPassword(headerMethod, updateCallback));
}
@@ -371,32 +374,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CUpdateOptions options;
options.Method = &methodMode;
- options.HeaderMethod = (_compressHeaders ||
- (methodMode.PasswordIsDefined && _encryptHeaders)) ?
- &headerMethod : 0;
+ options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter;
options.MaxFilter = _level >= 8;
options.HeaderOptions.CompressMainHeader = compressMainHeader;
- options.HeaderOptions.WriteModified = WriteModified;
- options.HeaderOptions.WriteCreated = WriteCreated;
- options.HeaderOptions.WriteAccessed = WriteAccessed;
+ options.HeaderOptions.WriteCTime = WriteCTime;
+ options.HeaderOptions.WriteATime = WriteATime;
+ options.HeaderOptions.WriteMTime = WriteMTime;
options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
options.RemoveSfxBlock = _removeSfxBlock;
options.VolumeMode = _volumeMode;
- return Update(
+
+ COutArchive archive;
+ CArchiveDatabase newDatabase;
+ HRESULT res = Update(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
- volume ? volume->Stream: 0,
- volume ? database: 0,
+ volume ? volume->Stream: 0,
+ volume ? db : 0,
#else
- _inStream,
- database,
+ _inStream,
+ db,
#endif
- updateItems, outStream, updateCallback, options);
+ updateItems,
+ archive, newDatabase, outStream, updateCallback, options);
+
+ RINOK(res);
+
+ updateItems.ClearAndFree();
+
+ return archive.WriteDatabase(EXTERNAL_CODECS_VARS
+ newDatabase, options.HeaderMethod, options.HeaderOptions);
+
COM_TRY_END
}
@@ -459,6 +472,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
return S_OK;
COM_TRY_END
-}
+}
}}