4.43 beta

This commit is contained in:
Igor Pavlov
2006-09-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0ec42ff829
commit 804edc5756
391 changed files with 9725 additions and 3168 deletions

View File

@@ -140,7 +140,7 @@ CDecoder::CDecoder(bool multiThread)
multiThread = true;
#endif
_multiThread = multiThread;
_bindInfoExPrevIsDefinded = false;
_bindInfoExPrevIsDefined = false;
#ifndef EXCLUDE_COM
LoadMethodMap();
#endif
@@ -176,7 +176,8 @@ HRESULT CDecoder::Decode(IInStream *inStream,
CLimitedSequentialInStream *streamSpec = new
CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream = streamSpec;
streamSpec->Init(lockedStreamImp, packSizes[j]);
streamSpec->SetStream(lockedStreamImp);
streamSpec->Init(packSizes[j]);
inStreams.Add(inStream);
}
@@ -185,7 +186,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
CBindInfoEx bindInfo;
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
bool createNewCoders;
if (!_bindInfoExPrevIsDefinded)
if (!_bindInfoExPrevIsDefined)
createNewCoders = true;
else
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
@@ -319,7 +320,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
}
}
_bindInfoExPrev = bindInfo;
_bindInfoExPrevIsDefinded = true;
_bindInfoExPrevIsDefined = true;
}
int i;
_mixerCoderCommon->ReInit();
@@ -336,7 +337,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (setDecoderProperties)
{
const CByteBuffer &properties = altCoderInfo.Properties;
@@ -365,7 +366,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
#ifndef _NO_CRYPTO
{
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
if (getTextPassword == 0)

View File

@@ -36,7 +36,7 @@ class CDecoder
CCoderLibraries _libraries;
#endif
bool _bindInfoExPrevIsDefinded;
bool _bindInfoExPrevIsDefined;
CBindInfoEx _bindInfoExPrev;
bool _multiThread;

View File

@@ -19,6 +19,7 @@ static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
#endif
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
static NArchive::N7z::CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 };
#ifdef COMPRESS_LZMA
#include "../../Compress/LZMA/LZMAEncoder.h"
@@ -207,9 +208,9 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
bool tryReduce = false;
UInt32 reducedDictionarySize = 1 << 10;
if (inSizeForReduce != 0 && methodFull.MethodID == k_LZMA)
if (inSizeForReduce != 0 && (methodFull.MethodID == k_LZMA || methodFull.MethodID == k_LZMA2))
{
while (true)
for (;;)
{
const UInt32 step = (reducedDictionarySize >> 1);
if (reducedDictionarySize >= *inSizeForReduce)
@@ -383,7 +384,8 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
inStreamSizeCountSpec->Init(inStream);
outStreamSizeCountSpec->Init(outStream);
outStreamSizeCountSpec->SetStream(outStream);
outStreamSizeCountSpec->Init();
CRecordVector<ISequentialInStream *> inStreamPointers;
CRecordVector<ISequentialOutStream *> outStreamPointers;
@@ -528,7 +530,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
// Make main stream first in list
int inIndex = _bindInfo.InStreams[0];
while (true)
for (;;)
{
UInt32 coderIndex, coderStreamIndex;
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);

View File

@@ -38,7 +38,8 @@ HRESULT CFolderInStream::OpenStream()
if (result != S_OK && result != S_FALSE)
return result;
_fileIndex++;
_inStreamWithHashSpec->Init(stream);
_inStreamWithHashSpec->SetStream(stream);
_inStreamWithHashSpec->Init();
if (!stream)
{
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));

View File

@@ -48,7 +48,8 @@ HRESULT CFolderOutStream::OpenFile()
UInt32 index = _startIndex + _currentIndex;
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
_outStreamWithHashSpec->Init(realOutStream);
_outStreamWithHashSpec->SetStream(realOutStream);
_outStreamWithHashSpec->Init();
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
(!realOutStream))
{

View File

@@ -40,7 +40,6 @@ CHandler::CHandler()
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
COM_TRY_BEGIN
*numItems =
#ifdef _7Z_VOL
_refs.Size();
@@ -48,10 +47,9 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
*numItems = _database.Files.Size();
#endif
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -59,13 +57,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
#ifdef _SFX
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
{
return E_NOTIMPL;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
@@ -79,8 +77,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
@@ -93,26 +91,6 @@ static void MySetFileTime(bool timeDefined, FILETIME unixTime,
propVariant = unixTime;
}
/*
inline static wchar_t GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
}
static UString ConvertBytesToHexString(const Byte *data, UInt32 size)
{
UString result;
for (UInt32 i = 0; i < size; i++)
{
Byte b = data[i];
result += GetHex(b >> 4);
result += GetHex(b & 0xF);
}
return result;
}
*/
#ifndef _SFX
static UString ConvertUInt32ToString(UInt32 value)
@@ -151,28 +129,48 @@ static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
static CMethodID k_Deflate64 = { { 0x4, 0x1, 0x9 }, 3 };
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
static inline char GetHex(Byte value)
static wchar_t GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
}
static inline UString GetHex2(Byte value)
{
UString result;
result += GetHex(value >> 4);
result += GetHex(value & 0xF);
result += GetHex((Byte)(value >> 4));
result += GetHex((Byte)(value & 0xF));
return result;
}
#endif
static CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
}
bool CHandler::IsEncrypted(UInt32 index2) const
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.Folders[folderIndex];
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
if (coderInfo.AltCoders[j].MethodID == k_AES)
return true;
}
}
return false;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -260,6 +258,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (item.IsFileCRCDefined)
propVariant = item.FileCRC;
break;
case kpidEncrypted:
{
propVariant = IsEncrypted(index2);
break;
}
#ifndef _SFX
case kpidMethod:
{
@@ -299,8 +302,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
methodName = L"PPMD";
else if (altCoderInfo.MethodID == k_Deflate)
methodName = L"Deflate";
else if (altCoderInfo.MethodID == k_Deflate64)
methodName = L"Deflate64";
else if (altCoderInfo.MethodID == k_BZip2)
methodName = L"BZip2";
else if (altCoderInfo.MethodID == k_AES)
methodName = L"7zAES";
else
methodIsKnown = false;
@@ -338,6 +345,32 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
methodsString += GetStringForSizeValue(dicSize);
}
}
else if (altCoderInfo.MethodID == k_AES)
{
if (altCoderInfo.Properties.GetCapacity() >= 1)
{
methodsString += L":";
const Byte *data = (const Byte *)altCoderInfo.Properties;
Byte firstByte = *data++;
UInt32 numCyclesPower = firstByte & 0x3F;
methodsString += ConvertUInt32ToString(numCyclesPower);
/*
if ((firstByte & 0xC0) != 0)
{
methodsString += L":";
return S_OK;
UInt32 saltSize = (firstByte >> 7) & 1;
UInt32 ivSize = (firstByte >> 6) & 1;
if (altCoderInfo.Properties.GetCapacity() >= 2)
{
Byte secondByte = *data++;
saltSize += (secondByte >> 4);
ivSize += (secondByte & 0x0F);
}
}
*/
}
}
else
{
if (altCoderInfo.Properties.GetCapacity() > 0)
@@ -345,7 +378,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
methodsString += L":[";
for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
{
if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
if (bi > 5 && bi + 1 < altCoderInfo.Properties.GetCapacity())
{
methodsString += L"..";
break;
@@ -517,7 +550,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{
openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
}
while(true)
for (;;)
{
CMyComPtr<IInStream> inStream;
if (!_volumes.IsEmpty())
@@ -724,8 +757,10 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
COM_TRY_BEGIN
#ifdef COMPRESS_MT
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
#endif
for (int i = 0; i < numProperties; i++)
{
@@ -740,7 +775,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
{
if(name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifdef COMPRESS_MT
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
#endif
continue;
}
else

View File

@@ -85,6 +85,9 @@ class CHandler:
public CMyUnknownImp
{
public:
#if !defined(_7Z_VOL) && !defined(__7Z_SET_PROPERTIES) && defined(EXTRACT_ONLY)
MY_UNKNOWN_IMP
#else
MY_QUERYINTERFACE_BEGIN
#ifdef _7Z_VOL
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
@@ -97,6 +100,8 @@ public:
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
#endif
STDMETHOD(Open)(IInStream *stream,
const UInt64 *maxCheckStartPosition,
@@ -167,6 +172,11 @@ private:
bool _compressHeadersFull;
bool _encryptHeaders;
bool WriteModified;
bool WriteCreated;
bool WriteAccessed;
bool _autoFilter;
UInt32 _level;
@@ -176,8 +186,7 @@ private:
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
HRESULT SetPassword(CCompressionMethodMode &methodMode,
IArchiveUpdateCallback *updateCallback);
HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback);
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo
@@ -191,7 +200,8 @@ private:
CCompressionMethodMode &headerMethod);
#endif
bool IsEncrypted(UInt32 index2) const;
#ifndef _SFX
CRecordVector<UInt64> _fileInfoPopIDs;
@@ -217,6 +227,11 @@ private:
_compressHeaders = true;
_compressHeadersFull = true;
_encryptHeaders = false;
WriteModified = true;
WriteCreated = false;
WriteAccessed = false;
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif

View File

@@ -24,6 +24,7 @@ namespace N7z {
#ifdef COMPRESS_LZMA
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
static CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 };
#endif
#ifdef COMPRESS_PPMD
@@ -64,6 +65,7 @@ static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
const wchar_t *kCopyMethod = L"Copy";
const wchar_t *kLZMAMethodName = L"LZMA";
const wchar_t *kLZMA2MethodName = L"LZMA2";
const wchar_t *kBZip2MethodName = L"BZip2";
const wchar_t *kPpmdMethodName = L"PPMd";
const wchar_t *kDeflateMethodName = L"Deflate";
@@ -121,9 +123,16 @@ static bool IsCopyMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kCopyMethod) == 0); }
static bool IsLZMAMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
{
return
(methodName.CompareNoCase(kLZMAMethodName) == 0) ||
(methodName.CompareNoCase(kLZMA2MethodName) == 0);
}
/*
static bool IsLZMethod(const UString &methodName)
{ return IsLZMAMethod(methodName); }
*/
static bool IsBZip2Method(const UString &methodName)
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
@@ -157,7 +166,8 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password));
if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined))
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
if (methodMode.PasswordIsDefined)
methodMode.Password = password;
}
else
@@ -532,6 +542,21 @@ HRESULT CHandler::SetCompressionMethod(
return S_OK;
}
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
{
filetimeIsDefined = false;
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(index, propID, &propVariant));
if (propVariant.vt == VT_FILETIME)
{
filetime = propVariant.filetime;
filetimeIsDefined = true;
}
else if (propVariant.vt != VT_EMPTY)
return E_INVALIDARG;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
@@ -583,8 +608,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItem.IsDirectory = fileItem.IsDirectory;
updateItem.Size = fileItem.UnPackSize;
updateItem.IsAnti = fileItem.IsAnti;
updateItem.CreationTime = fileItem.CreationTime;
updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
updateItem.LastWriteTime = fileItem.LastWriteTime;
updateItem.LastWriteTimeIsDefined = fileItem.IsLastWriteTimeDefined;
updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
updateItem.LastAccessTime = fileItem.LastAccessTime;
updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
}
if (updateItem.NewProperties)
@@ -604,32 +634,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItem.AttributesAreDefined = true;
}
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidCreationTime, &propVariant));
if (propVariant.vt == VT_EMPTY)
updateItem.CreationTimeIsDefined = false;
else if (propVariant.vt != VT_FILETIME)
return E_INVALIDARG;
else
{
updateItem.CreationTime = propVariant.filetime;
updateItem.CreationTimeIsDefined = true;
}
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
if (propVariant.vt == VT_EMPTY)
updateItem.LastWriteTimeIsDefined = false;
else if (propVariant.vt != VT_FILETIME)
return E_INVALIDARG;
else
{
updateItem.LastWriteTime = propVariant.filetime;
updateItem.LastWriteTimeIsDefined = 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));
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
@@ -671,8 +680,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (updateItem.IsAnti)
{
updateItem.AttributesAreDefined = false;
updateItem.CreationTimeIsDefined = false;
updateItem.LastWriteTimeIsDefined = false;
updateItem.IsCreationTimeDefined = false;
updateItem.IsLastWriteTimeDefined = false;
updateItem.IsLastAccessTimeDefined = false;
updateItem.Size = 0;
}
@@ -728,8 +740,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
&headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter;
options.MaxFilter = _level >= 8;
options.UseAdditionalHeaderStreams = useAdditionalHeaderStreams;
options.CompressMainHeader = compressMainHeader;
options.HeaderOptions.UseAdditionalHeaderStreams = useAdditionalHeaderStreams;
options.HeaderOptions.CompressMainHeader = compressMainHeader;
options.HeaderOptions.WriteModified = WriteModified;
options.HeaderOptions.WriteCreated = WriteCreated;
options.HeaderOptions.WriteAccessed = WriteAccessed;
options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
@@ -1048,6 +1065,21 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
RINOK(SetBoolProperty(_encryptHeaders, value));
continue;
}
else if (name.CompareNoCase(L"TM") == 0)
{
RINOK(SetBoolProperty(WriteModified, value));
continue;
}
else if (name.CompareNoCase(L"TC") == 0)
{
RINOK(SetBoolProperty(WriteCreated, value));
continue;
}
else if (name.CompareNoCase(L"TA") == 0)
{
RINOK(SetBoolProperty(WriteAccessed, value));
continue;
}
else if (name.CompareNoCase(L"V") == 0)
{
RINOK(SetBoolProperty(_volumeMode, value));

View File

@@ -9,6 +9,9 @@
#include "../../Common/StreamUtils.h"
#include "../../../Common/CRC.h"
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
// #define FORMAT_7Z_RECOVERY
namespace NArchive {
namespace N7z {
@@ -214,16 +217,16 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
UInt32 numPrevBytes = kSignatureSize - 1;
memmove(buffer, signature + 1, numPrevBytes);
UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
while(true)
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
return S_FALSE;
break;
UInt32 numReadBytes = kBufferSize - numPrevBytes;
RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize));
UInt32 numBytesInBuffer = numPrevBytes + processedSize;
if (numBytesInBuffer < kSignatureSize)
return S_FALSE;
break;
UInt32 numTests = numBytesInBuffer - kSignatureSize + 1;
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
{
@@ -237,6 +240,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
numPrevBytes = numBytesInBuffer - numTests;
memmove(buffer, buffer + numTests, numPrevBytes);
}
return S_FALSE;
}
// Out: _position must point to end of signature
@@ -335,9 +339,9 @@ HRESULT CInArchive::SkeepData()
return SkeepData(size);
}
HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo &archiveInfo)
HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
{
while(true)
for (;;)
{
UInt64 type;
RINOK(ReadID(type));
@@ -363,13 +367,13 @@ HRESULT CInArchive::GetNextFolderItem(CFolder &folder)
folder.Coders.Add(CCoderInfo());
CCoderInfo &coder = folder.Coders.Back();
while (true)
for (;;)
{
coder.AltCoders.Add(CAltCoderInfo());
CAltCoderInfo &altCoder = coder.AltCoders.Back();
Byte mainByte;
Byte mainByte = 0;
RINOK(ReadByte(mainByte));
altCoder.MethodID.IDSize = mainByte & 0xF;
altCoder.MethodID.IDSize = (Byte)(mainByte & 0xF);
RINOK(ReadBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize));
if ((mainByte & 0x10) != 0)
{
@@ -432,7 +436,7 @@ HRESULT CInArchive::GetNextFolderItem(CFolder &folder)
HRESULT CInArchive::WaitAttribute(UInt64 attribute)
{
while(true)
for (;;)
{
UInt64 type;
RINOK(ReadID(type));
@@ -453,7 +457,7 @@ HRESULT CInArchive::ReadHashDigests(int numItems,
digests.Reserve(numItems);
for(int i = 0; i < numItems; i++)
{
UInt32 crc;
UInt32 crc = 0;
if (digestsDefined[i])
RINOK(ReadUInt32(crc));
digests.Add(crc);
@@ -482,7 +486,7 @@ HRESULT CInArchive::ReadPackInfo(
}
UInt64 type;
while(true)
for (;;)
{
RINOK(ReadID(type));
if (type == NID::kEnd)
@@ -545,7 +549,7 @@ HRESULT CInArchive::ReadUnPackInfo(
}
}
while(true)
for (;;)
{
UInt64 type;
RINOK(ReadID(type));
@@ -578,7 +582,7 @@ HRESULT CInArchive::ReadSubStreamsInfo(
numUnPackStreamsInFolders.Clear();
numUnPackStreamsInFolders.Reserve(folders.Size());
UInt64 type;
while(true)
for (;;)
{
RINOK(ReadID(type));
if (type == NID::kNumUnPackStream)
@@ -638,7 +642,7 @@ HRESULT CInArchive::ReadSubStreamsInfo(
numDigestsTotal += numSubstreams;
}
while(true)
for (;;)
{
if (type == NID::kCRC)
{
@@ -697,7 +701,7 @@ HRESULT CInArchive::ReadStreamsInfo(
CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests)
{
while(true)
for (;;)
{
UInt64 type;
RINOK(ReadID(type));
@@ -732,7 +736,7 @@ HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files)
{
UString &name = files[i].Name;
name.Empty();
while (true)
for (;;)
{
wchar_t c;
RINOK(ReadWideCharLE(c));
@@ -748,7 +752,7 @@ HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
{
v.Clear();
v.Reserve(numItems);
Byte b;
Byte b = 0;
Byte mask = 0;
for(int i = 0; i < numItems; i++)
{
@@ -789,6 +793,8 @@ HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
{
CFileItem &file = files[i];
CArchiveFileTime fileTime;
fileTime.dwLowDateTime = 0;
fileTime.dwHighDateTime = 0;
bool defined = boolVector[i];
if (defined)
{
@@ -989,7 +995,7 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
// int sizePrev = -1;
// int posPrev = 0;
while(true)
for (;;)
{
/*
if (sizePrev >= 0)
@@ -1025,7 +1031,8 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
for(i = 0; i < numFiles; i++)
{
CFileItem &file = database.Files[i];
if (file.AreAttributesDefined = boolVector[i])
file.AreAttributesDefined = boolVector[i];
if (file.AreAttributesDefined)
{
RINOK(ReadUInt32(file.Attributes));
}
@@ -1041,7 +1048,8 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
for(i = 0; i < numFiles; i++)
{
CFileItem &file = database.Files[i];
if (file.IsStartPosDefined = boolVector[i])
file.IsStartPosDefined = boolVector[i];
if (file.IsStartPosDefined)
{
RINOK(ReadUInt64(file.StartPos));
}
@@ -1162,7 +1170,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
{
// v3.13 incorrectly worked with empty folders
// v4.07: Loop for skipping empty folders
while(true)
for (;;)
{
if (folderIndex >= Folders.Size())
throw CInArchiveException(CInArchiveException::kIncorrectHeader);
@@ -1208,19 +1216,52 @@ HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database
#endif
UInt32 crcFromArchive;
RINOK(SafeReadDirectUInt32(crcFromArchive));
UInt64 nextHeaderOffset;
UInt64 nextHeaderSize;
UInt32 nextHeaderCRC;
CCRC crc;
RINOK(SafeReadDirectUInt32(crcFromArchive));
RINOK(SafeReadDirectUInt64(nextHeaderOffset));
crc.UpdateUInt64(nextHeaderOffset);
RINOK(SafeReadDirectUInt64(nextHeaderSize));
crc.UpdateUInt64(nextHeaderSize);
RINOK(SafeReadDirectUInt32(nextHeaderCRC));
#ifdef FORMAT_7Z_RECOVERY
if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
{
UInt64 cur, cur2;
RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
const int kCheckSize = 500;
Byte buf[kCheckSize];
RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));
int checkSize = kCheckSize;
if (cur2 - cur < kCheckSize)
checkSize = (int)(cur2 - cur);
RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
UInt32 realProcessedSize;
RINOK(ReadDirect(buf, (UInt32)kCheckSize, &realProcessedSize));
int i;
for (i = (int)realProcessedSize - 2; i >= 0; i--)
if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
break;
if (i < 0)
return S_FALSE;
nextHeaderSize = realProcessedSize - i;
nextHeaderOffset = cur2 - cur + i;
nextHeaderCRC = CCRC::CalculateDigest(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, &_position));
}
#endif
crc.UpdateUInt64(nextHeaderOffset);
crc.UpdateUInt64(nextHeaderSize);
crc.UpdateUInt32(nextHeaderCRC);
#ifdef FORMAT_7Z_RECOVERY
crcFromArchive = crc.GetDigest();
#endif
#ifdef _7Z_VOL
UInt64 archiveStartOffset; // data offset from end if that struct
UInt64 additionalStartBlockSize; // start signature & start header size
@@ -1259,7 +1300,7 @@ HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database
CObjectVector<CByteBuffer> dataVector;
while (true)
for (;;)
{
UInt64 type;
RINOK(ReadID(type));

View File

@@ -201,13 +201,13 @@ private:
HRESULT ReadWideCharLE(wchar_t &c)
{
Byte b1;
Byte b1 = 0;
if (!_inByteBack->ReadByte(b1))
return E_FAIL;
Byte b2;
Byte b2 = 0;
if (!_inByteBack->ReadByte(b2))
return E_FAIL;
c = (wchar_t(b2) << 8) + b1;
c = (wchar_t)(((wchar_t)(b2) << 8) + b1);
return S_OK;
}

View File

@@ -9,17 +9,17 @@ namespace N7z {
static wchar_t GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
static bool HexCharToInt(wchar_t value, Byte &result)
{
if (value >= '0' && value <= '9')
result = value - '0';
result = (Byte)(value - '0');
else if (value >= 'a' && value <= 'f')
result = 10 + value - 'a';
result = (Byte)(10 + value - 'a');
else if (value >= 'A' && value <= 'F')
result = 10 + value - 'A';
result = (Byte)(10 + value - 'A');
else
return false;
return true;
@@ -32,7 +32,7 @@ static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result)
return false;
if (!HexCharToInt(valueLow, resultLow))
return false;
result = (resultHigh << 4) + resultLow;
result = (Byte)((resultHigh << 4) + resultLow);
return true;
}
@@ -42,8 +42,8 @@ UString CMethodID::ConvertToString() const
for (int i = 0; i < IDSize; i++)
{
Byte b = ID[i];
result += GetHex(b >> 4);
result += GetHex(b & 0xF);
result += GetHex((Byte)(b >> 4));
result += GetHex((Byte)(b & 0xF));
}
return result;
}
@@ -53,7 +53,7 @@ bool CMethodID::ConvertFromString(const UString &srcString)
int length = srcString.Length();
if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
return false;
IDSize = length / 2;
IDSize = (Byte)(length / 2);
UInt32 i;
for(i = 0; i < IDSize; i++)
if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))

View File

@@ -64,7 +64,7 @@ static void Load(const CSysString &folderPrefix)
continue;
if (propVariant.vt != VT_BSTR)
continue;
info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
info.MethodID.IDSize = (Byte)SysStringByteLen(propVariant.bstrVal);
memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
propVariant.Clear();

View File

@@ -274,7 +274,7 @@ HRESULT COutArchive::WriteFolder(const CFolder &folder)
size_t propertiesSize = altCoder.Properties.GetCapacity();
Byte b;
b = altCoder.MethodID.IDSize & 0xF;
b = (Byte)(altCoder.MethodID.IDSize & 0xF);
bool isComplex = !coder.IsSimpleCoder();
b |= (isComplex ? 0x10 : 0);
b |= ((propertiesSize != 0) ? 0x20 : 0 );
@@ -548,6 +548,8 @@ HRESULT COutArchive::WriteTime(
{
const CFileItem &item = files[i];
CArchiveFileTime timeValue;
timeValue.dwLowDateTime = 0;
timeValue.dwHighDateTime = 0;
switch(type)
{
case NID::kCreationTime:
@@ -608,7 +610,9 @@ static void WriteUInt64ToBuffer(Byte *data, UInt64 value)
HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
const CCompressionMethodMode *options, UInt64 &headerOffset)
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions,
UInt64 &headerOffset)
{
CObjectVector<CFolder> folders;
@@ -628,7 +632,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
//////////////////////////
// Folders
CNum externalFoldersStreamIndex;
CNum externalFoldersStreamIndex = 0;
bool externalFolders = (compressHeaders && database.Folders.Size() > 8);
if (externalFolders)
{
@@ -675,7 +679,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
}
CByteBuffer namesData;
CNum externalNamesStreamIndex;
CNum externalNamesStreamIndex = 0;
bool externalNames = (compressHeaders && database.Files.Size() > 8);
if (numDefinedNames > 0)
{
@@ -715,7 +719,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
}
CByteBuffer attributesData;
CNum externalAttributesStreamIndex;
CNum externalAttributesStreamIndex = 0;
bool externalAttributes = (compressHeaders && numDefinedAttributes > 8);
if (numDefinedAttributes > 0)
{
@@ -751,7 +755,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
}
CByteBuffer startsData;
CNum externalStartStreamIndex;
CNum externalStartStreamIndex = 0;
bool externalStarts = (compressHeaders && numDefinedStarts > 8);
if (numDefinedStarts > 0)
{
@@ -775,7 +779,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
/////////////////////////////////
// Write Last Write Time
CNum externalLastWriteTimeStreamIndex;
CNum externalLastWriteTimeStreamIndex = 0;
bool externalLastWriteTime = false;
// /*
CNum numDefinedLastWriteTimes = 0;
@@ -949,11 +953,20 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
}
RINOK(WriteTime(database.Files, NID::kCreationTime, false, 0));
RINOK(WriteTime(database.Files, NID::kLastAccessTime, false, 0));
RINOK(WriteTime(database.Files, NID::kLastWriteTime,
if (headerOptions.WriteCreated)
{
RINOK(WriteTime(database.Files, NID::kCreationTime, false, 0));
}
if (headerOptions.WriteModified)
{
RINOK(WriteTime(database.Files, NID::kLastWriteTime,
// false, 0));
externalLastWriteTime, externalLastWriteTimeStreamIndex));
}
if (headerOptions.WriteAccessed)
{
RINOK(WriteTime(database.Files, NID::kLastAccessTime, false, 0));
}
if (numDefinedAttributes > 0)
{
@@ -1031,7 +1044,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database,
const CCompressionMethodMode *options,
bool useAdditionalStreams, bool compressMainHeader)
const CHeaderOptions &headerOptions)
{
UInt64 headerOffset;
UInt32 headerCRC;
@@ -1051,23 +1064,23 @@ HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database,
if (options->IsEmpty())
options = 0;
const CCompressionMethodMode *additionalStreamsOptions = options;
if (!useAdditionalStreams)
if (!headerOptions.UseAdditionalHeaderStreams)
additionalStreamsOptions = 0;
/*
if (database.Files.Size() < 2)
compressMainHeader = false;
*/
if (options != 0)
if (options->PasswordIsDefined || compressMainHeader)
if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
_dynamicMode = true;
RINOK(WriteHeader(database, additionalStreamsOptions, headerOffset));
RINOK(WriteHeader(database, additionalStreamsOptions, headerOptions, headerOffset));
if (_dynamicMode)
{
CCompressionMethodMode encryptOptions;
encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
encryptOptions.Password = options->Password;
CEncoder encoder(compressMainHeader ? *options : encryptOptions);
CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
CRecordVector<UInt64> packSizes;
CObjectVector<CFolder> folders;
RINOK(EncodeStream(encoder, _dynamicBuffer,

View File

@@ -60,6 +60,21 @@ public:
size_t GetSize() const { return _pos; }
};
struct CHeaderOptions
{
bool UseAdditionalHeaderStreams;
bool CompressMainHeader;
bool WriteModified;
bool WriteCreated;
bool WriteAccessed;
CHeaderOptions():
UseAdditionalHeaderStreams(false),
CompressMainHeader(true),
WriteModified(true),
WriteCreated(false),
WriteAccessed(false) {}
};
class COutArchive
{
@@ -127,6 +142,7 @@ class COutArchive
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT WriteHeader(const CArchiveDatabase &database,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
bool _mainMode;
@@ -162,8 +178,7 @@ public:
HRESULT SkeepPrefixArchiveHeader();
HRESULT WriteDatabase(const CArchiveDatabase &database,
const CCompressionMethodMode *options,
bool useAdditionalHeaderStreams,
bool compressMainHeader);
const CHeaderOptions &headerOptions);
#ifdef _7Z_VOL
static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);

View File

@@ -43,7 +43,8 @@ static HRESULT WriteRange(
CLimitedSequentialInStream *streamSpec = new
CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
streamSpec->Init(inStream, size);
streamSpec->SetStream(inStream);
streamSpec->Init(size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
@@ -195,49 +196,125 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param)
const CUpdateItem &u1 = updateItems[*p1];
const CUpdateItem &u2 = updateItems[*p2];
if (u1.IsDirectory != u2.IsDirectory)
{
if (u1.IsDirectory)
return u1.IsAnti ? 1: -1;
return u2.IsAnti ? -1: 1;
}
return (u1.IsDirectory) ? 1 : -1;
if (u1.IsDirectory)
{
if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1);
int n = MyStringCompareNoCase(u1.Name, u2.Name);
return (u1.IsAnti ? (-n) : n);
return -n;
}
if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1);
return MyStringCompareNoCase(u1.Name, u2.Name);
}
static const char *g_Exts =
" lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
" zip jar ear war msi"
" 3gp avi mov mpeg mpg mpe wmv"
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
" swf "
" chm hxi hxs"
" gif jpeg jpg jp2 png tiff bmp ico psd psp"
" awg ps eps cgm dxf svg vrml wmf emf ai md"
" cad dwg pps key sxi"
" max 3ds"
" iso bin nrg mdf img pdi tar cpio xpi"
" vfd vhd vud vmc vsv"
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
" f77 f f90 f95"
" asm sql manifest dep "
" mak clw csproj vcproj sln dsp dsw "
" class "
" bat cmd"
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
" awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
" abw afp cwk lwp wpd wps wpt wrf wri"
" abf afm bdf fon mgf otf pcf pfa snf ttf"
" dbf mdb nsf ntf wdb db fdb gdb"
" exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
" pdb pch idb ncb opt";
int GetExtIndex(const char *ext)
{
int extIndex = 1;
const char *p = g_Exts;
for (;;)
{
char c = *p++;
if (c == 0)
return extIndex;
if (c == ' ')
continue;
int pos = 0;
for (;;)
{
char c2 = ext[pos++];
if (c2 == 0 && (c == 0 || c == ' '))
return extIndex;
if (c != c2)
break;
c = *p++;
}
extIndex++;
for (;;)
{
if (c == 0)
return extIndex;
if (c == ' ')
break;
c = *p++;
}
}
}
struct CRefItem
{
UInt32 Index;
const CUpdateItem *UpdateItem;
UInt32 ExtensionPos;
UInt32 NamePos;
bool SortByType;
int ExtensionIndex;
CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
SortByType(sortByType),
Index(index),
UpdateItem(&updateItem),
ExtensionPos(0),
NamePos(0)
NamePos(0),
ExtensionIndex(0)
{
if (sortByType)
{
int slashPos = GetReverseSlashPos(updateItem.Name);
if (slashPos >= 0)
NamePos = slashPos + 1;
else
NamePos = 0;
NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
int dotPos = updateItem.Name.ReverseFind(L'.');
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
ExtensionPos = updateItem.Name.Length();
else
{
ExtensionPos = dotPos + 1;
UString us = updateItem.Name.Mid(ExtensionPos);
if (!us.IsEmpty())
{
us.MakeLower();
int i;
AString s;
for (i = 0; i < us.Length(); i++)
{
wchar_t c = us[i];
if (c >= 0x80)
break;
s += (char)c;
}
if (i == us.Length())
ExtensionIndex = GetExtIndex(s);
else
ExtensionIndex = 0;
}
}
}
}
};
@@ -250,23 +327,21 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
const CUpdateItem &u2 = *a2.UpdateItem;
int n;
if (u1.IsDirectory != u2.IsDirectory)
{
if (u1.IsDirectory)
return u1.IsAnti ? 1: -1;
return u2.IsAnti ? -1: 1;
}
return (u1.IsDirectory) ? 1 : -1;
if (u1.IsDirectory)
{
if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1);
n = MyStringCompareNoCase(u1.Name, u2.Name);
return (u1.IsAnti ? (-n) : n);
return -n;
}
if (a1.SortByType)
bool sortByType = *(bool *)param;
if (sortByType)
{
RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined)
if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
RINOZ(MyCompare(u1.Size, u2.Size))
}
@@ -448,11 +523,12 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
if (updateItem.AttributesAreDefined)
file.SetAttributes(updateItem.Attributes);
// if (updateItem.CreationTimeIsDefined)
// file.SetCreationTime(updateItem.ItemInfo.CreationTime);
if (updateItem.LastWriteTimeIsDefined)
if (updateItem.IsCreationTimeDefined)
file.SetCreationTime(updateItem.CreationTime);
if (updateItem.IsLastWriteTimeDefined)
file.SetLastWriteTime(updateItem.LastWriteTime);
if (updateItem.IsLastAccessTimeDefined)
file.SetLastAccessTime(updateItem.LastAccessTime);
file.UnPackSize = updateItem.Size;
file.IsDirectory = updateItem.IsDirectory;
@@ -485,7 +561,8 @@ static HRESULT Update2(
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
streamSpec->Init(inStream, startBlockSize);
streamSpec->SetStream(inStream);
streamSpec->Init(startBlockSize);
RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
}
@@ -534,36 +611,6 @@ static HRESULT Update2(
CArchiveDatabase newDatabase;
/////////////////////////////////////////
// Write Empty Files & Folders
CRecordVector<int> emptyRefs;
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
if (updateItem.NewData)
{
if (updateItem.HasStream())
continue;
}
else
if (updateItem.IndexInArchive != -1)
if (database->Files[updateItem.IndexInArchive].HasStream)
continue;
emptyRefs.Add(i);
}
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
for(i = 0; i < emptyRefs.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
CFileItem file;
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
else
file = database->Files[updateItem.IndexInArchive];
newDatabase.Files.Add(file);
}
////////////////////////////
COutArchive archive;
@@ -664,10 +711,10 @@ static HRESULT Update2(
continue;
CRecordVector<CRefItem> refItems;
refItems.Reserve(numFiles);
bool sortByType = (numSolidFiles > 1);
for (i = 0; i < numFiles; i++)
refItems.Add(CRefItem(group.Indices[i],
updateItems[group.Indices[i]], numSolidFiles > 1));
refItems.Sort(CompareUpdateItems, 0);
refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));
refItems.Sort(CompareUpdateItems, (void *)&sortByType);
CRecordVector<UInt32> indices;
indices.Reserve(numFiles);
@@ -780,15 +827,49 @@ static HRESULT Update2(
i += numSubFiles;
}
}
{
/////////////////////////////////////////
// Write Empty Files & Folders
CRecordVector<int> emptyRefs;
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
if (updateItem.NewData)
{
if (updateItem.HasStream())
continue;
}
else
if (updateItem.IndexInArchive != -1)
if (database->Files[updateItem.IndexInArchive].HasStream)
continue;
emptyRefs.Add(i);
}
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
for(i = 0; i < emptyRefs.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
CFileItem file;
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
else
file = database->Files[updateItem.IndexInArchive];
newDatabase.Files.Add(file);
}
}
/*
if (newDatabase.Files.Size() != updateItems.Size())
return E_FAIL;
*/
return archive.WriteDatabase(newDatabase, options.HeaderMethod,
options.UseAdditionalHeaderStreams, options.CompressMainHeader);
return archive.WriteDatabase(newDatabase, options.HeaderMethod, options.HeaderOptions);
}
#ifdef _7Z_VOL
static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
{
CAltCoderInfo altCoder;
@@ -831,7 +912,6 @@ static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CU
false);
}
#ifdef _7Z_VOL
HRESULT UpdateVolume(
IInStream *inStream,
const CArchiveDatabaseEx *database,

View File

@@ -4,6 +4,7 @@
#define __7Z_UPDATE_H
#include "7zIn.h"
#include "7zOut.h"
#include "7zCompressionMode.h"
#include "../IArchive.h"
@@ -21,6 +22,7 @@ struct CUpdateItem
UInt32 Attributes;
FILETIME CreationTime;
FILETIME LastWriteTime;
FILETIME LastAccessTime;
UInt64 Size;
UString Name;
@@ -28,13 +30,20 @@ struct CUpdateItem
bool IsAnti;
bool IsDirectory;
bool CreationTimeIsDefined;
bool LastWriteTimeIsDefined;
bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
bool AttributesAreDefined;
const bool HasStream() const
{ return !IsDirectory && !IsAnti && Size != 0; }
CUpdateItem(): IsAnti(false) {}
CUpdateItem():
IsAnti(false),
AttributesAreDefined(false),
IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false)
{}
void SetDirectoryStatusFromAttributes()
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
@@ -48,8 +57,9 @@ struct CUpdateOptions
const CCompressionMethodMode *HeaderMethod;
bool UseFilters;
bool MaxFilter;
bool UseAdditionalHeaderStreams;
bool CompressMainHeader;
CHeaderOptions HeaderOptions;
UInt64 NumSolidFiles;
UInt64 NumSolidBytes;
bool SolidExtension;

View File

@@ -38,6 +38,8 @@ SZ_RESULT SzExtract(
Byte *inBuffer = 0;
size_t processedSize;
#endif
if (unPackSize != (size_t)unPackSize)
return SZE_OUTOFMEMORY;
*blockIndex = folderIndex;
allocMain->Free(*outBuffer);
*outBuffer = 0;

View File

@@ -44,18 +44,8 @@ CFileSize GetFilePackSize(int fileIndex) const
}
*/
SZ_RESULT MySzInAlloc(void **p, size_t size, void * (*allocFunc)(size_t size))
{
if (size == 0)
*p = 0;
else
{
*p = allocFunc(size);
RINOM(*p);
}
return SZ_OK;
}
#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
{
@@ -64,14 +54,14 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
UInt32 i;
UInt32 folderIndex = 0;
UInt32 indexInFolder = 0;
RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
for(i = 0; i < db->Database.NumFolders; i++)
{
db->FolderStartPackStreamIndex[i] = startPos;
startPos += db->Database.Folders[i].NumPackStreams;
}
RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc));
MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
for(i = 0; i < db->Database.NumPackStreams; i++)
{
@@ -79,8 +69,8 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
startPosSize += db->Database.PackSizes[i];
}
RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
for (i = 0; i < db->Database.NumFiles; i++)
{
@@ -97,7 +87,7 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
v3.13 incorrectly worked with empty folders
v4.07: Loop for skipping empty folders
*/
while(1)
for (;;)
{
if (folderIndex >= db->Database.NumFolders)
return SZE_ARCHIVE_ERROR;
@@ -237,7 +227,7 @@ SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value)
{
Byte b;
RINOK(SafeReadDirectByte(inStream, &b));
*value |= ((UInt32)b << (8 * i));
*value |= ((UInt64)b << (8 * i));
}
return SZ_OK;
}
@@ -355,7 +345,7 @@ SZ_RESULT SzSkeepData(CSzData *sd)
SZ_RESULT SzReadArchiveProperties(CSzData *sd)
{
while(1)
for (;;)
{
UInt64 type;
RINOK(SzReadID(sd, &type));
@@ -368,7 +358,7 @@ SZ_RESULT SzReadArchiveProperties(CSzData *sd)
SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
{
while(1)
for (;;)
{
UInt64 type;
RINOK(SzReadID(sd, &type));
@@ -385,8 +375,8 @@ SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allo
Byte b = 0;
Byte mask = 0;
size_t i;
RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
for(i = 0; i < numItems; i++)
MY_ALLOC(Byte, *v, numItems, allocFunc);
for (i = 0; i < numItems; i++)
{
if (mask == 0)
{
@@ -406,7 +396,7 @@ SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*all
RINOK(SzReadByte(sd, &allAreDefined));
if (allAreDefined == 0)
return SzReadBoolVector(sd, numItems, v, allocFunc);
RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
MY_ALLOC(Byte, *v, numItems, allocFunc);
for(i = 0; i < numItems; i++)
(*v)[i] = 1;
return SZ_OK;
@@ -421,7 +411,7 @@ SZ_RESULT SzReadHashDigests(
{
size_t i;
RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, *digests, numItems, allocFunc);
for(i = 0; i < numItems; i++)
if ((*digestsDefined)[i])
{
@@ -445,14 +435,14 @@ SZ_RESULT SzReadPackInfo(
RINOK(SzWaitAttribute(sd, k7zIdSize));
RINOK(MySzInAlloc((void **)packSizes, (size_t)*numPackStreams * sizeof(CFileSize), allocFunc));
MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
for(i = 0; i < *numPackStreams; i++)
{
RINOK(SzReadSize(sd, (*packSizes) + i));
}
while(1)
for (;;)
{
UInt64 type;
RINOK(SzReadID(sd, &type));
@@ -467,8 +457,8 @@ SZ_RESULT SzReadPackInfo(
}
if (*packCRCsDefined == 0)
{
RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(Byte), allocFunc));
RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), allocFunc));
MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
for(i = 0; i < *numPackStreams; i++)
{
(*packCRCsDefined)[i] = 0;
@@ -496,7 +486,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
RINOK(SzReadNumber32(sd, &numCoders));
folder->NumCoders = numCoders;
RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc));
MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
for (i = 0; i < numCoders; i++)
SzCoderInfoInit(folder->Coders + i);
@@ -553,7 +543,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
folder->NumBindPairs = numBindPairs;
RINOK(MySzInAlloc((void **)&folder->BindPairs, (size_t)numBindPairs * sizeof(CBindPair), allocFunc));
MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
for (i = 0; i < numBindPairs; i++)
{
@@ -565,7 +555,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
numPackedStreams = numInStreams - (UInt32)numBindPairs;
folder->NumPackStreams = numPackedStreams;
RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
if (numPackedStreams == 1)
{
@@ -599,8 +589,7 @@ SZ_RESULT SzReadUnPackInfo(
{
RINOK(SzReadSwitch(sd));
RINOK(MySzInAlloc((void **)folders, (size_t)*numFolders * sizeof(CFolder), allocFunc));
MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
for(i = 0; i < *numFolders; i++)
SzFolderInit((*folders) + i);
@@ -619,7 +608,7 @@ SZ_RESULT SzReadUnPackInfo(
CFolder *folder = (*folders) + i;
UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc));
MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
for(j = 0; j < numOutStreams; j++)
{
@@ -627,7 +616,7 @@ SZ_RESULT SzReadUnPackInfo(
}
}
while(1)
for (;;)
{
UInt64 type;
RINOK(SzReadID(sd, &type));
@@ -676,7 +665,7 @@ SZ_RESULT SzReadSubStreamsInfo(
folders[i].NumUnPackStreams = 1;
*numUnPackStreams = numFolders;
while(1)
for (;;)
{
RINOK(SzReadID(sd, &type));
if (type == k7zIdNumUnPackStream)
@@ -756,7 +745,7 @@ SZ_RESULT SzReadSubStreamsInfo(
si = 0;
while(1)
for (;;)
{
if (type == k7zIdCRC)
{
@@ -814,7 +803,7 @@ SZ_RESULT SzReadStreamsInfo(
void * (*allocFunc)(size_t size),
ISzAlloc *allocTemp)
{
while(1)
for (;;)
{
UInt64 type;
RINOK(SzReadID(sd, &type));
@@ -887,7 +876,7 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
len += numAdds;
}
RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc));
MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
len = 0;
while(2 <= sd->Size)
@@ -973,13 +962,13 @@ SZ_RESULT SzReadHeader2(
RINOK(SzReadNumber32(sd, &numFiles));
db->Database.NumFiles = numFiles;
RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocMain->Alloc));
MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
db->Database.Files = files;
for(i = 0; i < numFiles; i++)
SzFileInit(files + i);
while(1)
for (;;)
{
UInt64 type;
UInt64 size;
@@ -1122,7 +1111,7 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
for (i = 0; i < db->NumPackStreams; i++)
packSize += db->PackSizes[i];
RINOK(MySzInAlloc((void **)inBuffer, (size_t)packSize, allocTemp->Alloc));
MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
#endif
@@ -1238,9 +1227,10 @@ SZ_RESULT SzArchiveOpen2(
res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
if (res == SZ_OK)
{
res = SZE_ARCHIVE_ERROR;
if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize))
{
while (1)
for (;;)
{
UInt64 type;
sd.Data = buffer.Items;

View File

@@ -1,21 +1,122 @@
/*
7zMain.c
Test application for 7z Decoder
LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02)
LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#define USE_WINDOWS_FUNCTIONS
#endif
#ifdef USE_WINDOWS_FUNCTIONS
#include <windows.h>
#endif
#include "7zCrc.h"
#include "7zIn.h"
#include "7zExtract.h"
#ifdef USE_WINDOWS_FUNCTIONS
typedef HANDLE MY_FILE_HANDLE;
#else
typedef FILE *MY_FILE_HANDLE;
#endif
void ConvertNumberToString(CFileSize value, char *s)
{
char temp[32];
int pos = 0;
do
{
temp[pos++] = (char)('0' + (int)(value % 10));
value /= 10;
}
while (value != 0);
do
*s++ = temp[--pos];
while(pos > 0);
*s = '\0';
}
#ifdef USE_WINDOWS_FUNCTIONS
// ReadFile and WriteFile functions in Windows have BUG:
// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
// (Insufficient system resources exist to complete the requested service).
#define kChunkSizeMax (1 << 24)
#endif
size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
{
if (size == 0)
return 0;
#ifdef USE_WINDOWS_FUNCTIONS
{
size_t processedSize = 0;
do
{
DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
DWORD processedLoc = 0;
BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL);
data = (void *)((unsigned char *)data + processedLoc);
size -= processedLoc;
processedSize += processedLoc;
if (!res || processedLoc == 0)
break;
}
while (size > 0);
return processedSize;
}
#else
return fread(data, 1, size, file);
#endif
}
size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
{
if (size == 0)
return 0;
#ifdef USE_WINDOWS_FUNCTIONS
{
size_t processedSize = 0;
do
{
DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
DWORD processedLoc = 0;
BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL);
data = (void *)((unsigned char *)data + processedLoc);
size -= processedLoc;
processedSize += processedLoc;
if (!res)
break;
}
while (size > 0);
return processedSize;
}
#else
return fwrite(data, 1, size, file);
#endif
}
int MyCloseFile(MY_FILE_HANDLE file)
{
#ifdef USE_WINDOWS_FUNCTIONS
return (CloseHandle(file) != FALSE) ? 0 : 1;
#else
return fclose(file);
#endif
}
typedef struct _CFileInStream
{
ISzInStream InStream;
FILE *File;
MY_FILE_HANDLE File;
} CFileInStream;
#ifdef _LZMA_IN_CB
@@ -29,7 +130,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz
size_t processedSizeLoc;
if (maxRequiredSize > kBufferSize)
maxRequiredSize = kBufferSize;
processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File);
processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize);
*buffer = g_Buffer;
if (processedSize != 0)
*processedSize = processedSizeLoc;
@@ -41,7 +142,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
{
CFileInStream *s = (CFileInStream *)object;
size_t processedSizeLoc = fread(buffer, 1, size, s->File);
size_t processedSizeLoc = MyReadFile(s->File, buffer, size);
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
@@ -52,10 +153,24 @@ SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *process
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
CFileInStream *s = (CFileInStream *)object;
#ifdef USE_WINDOWS_FUNCTIONS
{
LARGE_INTEGER value;
value.LowPart = (DWORD)pos;
value.HighPart = (LONG)(pos >> 32);
value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN);
if (value.LowPart == 0xFFFFFFFF)
if(GetLastError() != NO_ERROR)
return SZE_FAIL;
return SZ_OK;
}
#else
int res = fseek(s->File, (long)pos, SEEK_SET);
if (res == 0)
return SZ_OK;
return SZE_FAIL;
#endif
}
void PrintError(char *sz)
@@ -71,7 +186,7 @@ int main(int numargs, char *args[])
ISzAlloc allocImp;
ISzAlloc allocTempImp;
printf("\n7z ANSI-C Decoder 4.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n");
printf("\n7z ANSI-C Decoder 4.44 Copyright (c) 1999-2006 Igor Pavlov 2006-08-27\n");
if (numargs == 1)
{
printf(
@@ -88,8 +203,15 @@ int main(int numargs, char *args[])
return 1;
}
archiveStream.File =
#ifdef USE_WINDOWS_FUNCTIONS
CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (archiveStream.File == INVALID_HANDLE_VALUE)
#else
archiveStream.File = fopen(args[2], "rb");
if (archiveStream.File == 0)
#endif
{
PrintError("can not open input file");
return 1;
@@ -126,18 +248,22 @@ int main(int numargs, char *args[])
for (i = 0; i < db.Database.NumFiles; i++)
{
CFileItem *f = db.Database.Files + i;
printf("%10d %s\n", (int)f->Size, f->Name);
char s[32];
ConvertNumberToString(f->Size, s);
printf("%10s %s\n", s, f->Name);
}
}
else if (testCommand || extractCommand)
{
UInt32 i;
// if you need cache, use these 3 variables.
// if you use external function, you can make these variable as static.
UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
Byte *outBuffer = 0; // it must be 0 before first call for each new archive.
size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0)
/*
if you need cache, use these 3 variables.
if you use external function, you can make these variable as static.
*/
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
printf("\n");
for (i = 0; i < db.Database.NumFiles; i++)
@@ -165,7 +291,7 @@ int main(int numargs, char *args[])
break;
if (!testCommand)
{
FILE *outputHandle;
MY_FILE_HANDLE outputHandle;
UInt32 processedSize;
char *fileName = f->Name;
size_t nameLen = strlen(f->Name);
@@ -176,21 +302,28 @@ int main(int numargs, char *args[])
break;
}
outputHandle = fopen(fileName, "wb+");
outputHandle =
#ifdef USE_WINDOWS_FUNCTIONS
CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (outputHandle == INVALID_HANDLE_VALUE)
#else
fopen(fileName, "wb+");
if (outputHandle == 0)
#endif
{
PrintError("can not open output file");
res = SZE_FAIL;
break;
}
processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed);
if (processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZE_FAIL;
break;
}
if (fclose(outputHandle))
if (MyCloseFile(outputHandle))
{
PrintError("can not close output file");
res = SZE_FAIL;
@@ -209,7 +342,7 @@ int main(int numargs, char *args[])
}
SzArDbExFree(&db, allocImp.Free);
fclose(archiveStream.File);
MyCloseFile(archiveStream.File);
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");

View File

@@ -3,32 +3,38 @@
#ifndef __COMMON_TYPES_H
#define __COMMON_TYPES_H
#ifndef UInt32
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long
typedef unsigned long UInt32;
#else
#define UInt32 unsigned int
#endif
#endif
#ifndef Byte
#define Byte unsigned char
#endif
#ifndef UInt16
#define UInt16 unsigned short
typedef unsigned int UInt32;
#endif
#endif
/* #define _SZ_NO_INT_64 */
/* define it your compiler doesn't support long long int */
#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
#ifdef _SZ_NO_INT_64
#define UInt64 unsigned long
typedef unsigned long UInt64;
#else
#ifdef _MSC_VER
#define UInt64 unsigned __int64
typedef unsigned __int64 UInt64;
#else
#define UInt64 unsigned long long int
typedef unsigned long long int UInt64;
#endif
#endif
#endif
@@ -38,9 +44,9 @@
#ifndef CFileSize
#ifdef _SZ_FILE_SIZE_64
#define CFileSize UInt64
typedef UInt64 CFileSize;
#else
#define CFileSize UInt32
typedef UInt32 CFileSize;
#endif
#endif

View File

@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /D "_SZ_FILE_SIZE_64" /YX /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /D "_SZ_FILE_SIZE_64" /YX /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -93,6 +93,10 @@ SOURCE=..\..\Compress\LZMA_C\LzmaDecode.c
SOURCE=..\..\Compress\LZMA_C\LzmaDecode.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\LZMA_C\LzmaTypes.h
# End Source File
# End Group
# Begin Source File

View File

@@ -87,7 +87,7 @@ STATPROPSTG kProperties[] =
CHandler::CHandler()
{}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -117,8 +117,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
@@ -225,7 +225,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
UInt64 numFiles = _items.Size();
RINOK(callback->SetCompleted(&numFiles, NULL));
}
while(true)
for (;;)
{
CItemEx itemInfo;
bool filled;
@@ -328,7 +328,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
{
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
@@ -337,7 +338,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 pos;
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
streamSpec->Init(_stream, itemInfo.PackSize);
streamSpec->SetStream(_stream);
streamSpec->Init(itemInfo.PackSize);
CLocalProgress *localProgressSpec = new CLocalProgress;

View File

@@ -25,7 +25,7 @@ HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
static inline UInt16 GetUInt16FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8);
return (UInt16)(p[0] | (((UInt16)p[1]) << 8));
}
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
@@ -79,7 +79,7 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
UInt32 numBytesPrev = processedSize - 1;
memmove(buffer, buffer + 1, numBytesPrev);
UInt64 curTestPos = _streamStartPosition + 1;
while(true)
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
@@ -192,7 +192,7 @@ bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
return false;
if (!ReadBlock2())
return false;
while(true)
for (;;)
if (!ReadBlock())
break;
return true;
@@ -270,7 +270,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
for (; _blockPos < _blockSize;)
item.Name += (char)ReadByte();
while(true)
for (;;)
if (!ReadBlock())
break;

View File

@@ -13,7 +13,7 @@ DEFINE_GUID(CLSID_CArjHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
{
return TRUE;
}

View File

@@ -38,7 +38,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidPackedSize, VT_UI8},
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -68,8 +68,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
@@ -101,8 +101,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
try
@@ -219,10 +219,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
HRESULT result;
HRESULT result = S_OK;
bool firstItem = true;
while(true)
for (;;)
{
localCompressProgressSpec->Init(progress,
&currentTotalPacked,

View File

@@ -33,8 +33,7 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
return S_OK;
}
static HRESULT CopyStreams(ISequentialInStream *inStream,
ISequentialOutStream *outStream, IArchiveUpdateCallback *updateCallback)
static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream)
{
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
@@ -101,7 +100,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (indexInArchive != 0)
return E_INVALIDARG;
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
return CopyStreams(_stream, outStream, updateCallback);
return CopyStreams(_stream, outStream);
}
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)

View File

@@ -68,7 +68,7 @@ static const wchar_t *kMethods[] =
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
static const wchar_t *kUnknownMethod = L"Unknown";
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -101,8 +101,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
@@ -153,7 +153,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
case kpidMethod:
{
UInt16 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
const CFolder &folder = db.Folders[realFolderIndex];
int methodIndex = folder.GetCompressionMethod();
UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
@@ -223,7 +223,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
{
COM_TRY_BEGIN
Close();
HRESULT res;
HRESULT res = S_FALSE;
CInArchive archive;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
{
@@ -269,7 +269,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
RINOK(openArchiveCallback->SetCompleted(&numItems, NULL));
nextStream = 0;
while(true)
for (;;)
{
const COtherArchive *otherArchive = 0;
if (!prevChecked)
@@ -511,7 +511,7 @@ HRESULT CCabFolderOutStream::FlushCorrupted()
Byte buffer[kBufferSize];
for (int i = 0; i < kBufferSize; i++)
buffer[i] = 0;
while(true)
for (;;)
{
UInt64 remain = GetRemain();
if (remain == 0)
@@ -548,7 +548,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
return S_OK;
bool testMode = (_aTestMode != 0);
UInt64 totalUnPacked = 0;
int lastIndex = 0;
UInt32 i;
int lastFolder = -2;
@@ -806,10 +805,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
COM_TRY_BEGIN
*numItems = m_Database.Items.Size();
return S_OK;
COM_TRY_END
}
}}

View File

@@ -12,6 +12,7 @@
namespace NArchive{
namespace NCab{
/*
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
{
UInt32 realProcessedSize;
@@ -37,6 +38,7 @@ static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
if(realProcessedSize != size)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
}
*/
Byte CInArchive::ReadByte()
{
@@ -71,7 +73,7 @@ UInt32 CInArchive::ReadUInt32()
AString CInArchive::SafeReadName()
{
AString name;
while(true)
for (;;)
{
Byte b = ReadByte();
if (b == 0)
@@ -107,7 +109,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
UInt64 value = 0;
const int kSignatureSize = 8;
UInt64 kSignature64 = NHeader::NArchive::kSignature;
while(true)
for (;;)
{
Byte b;
if (!inBuffer.ReadByte(b))

View File

@@ -57,7 +57,7 @@ STATPROPSTG kProperties[] =
static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]);
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -90,8 +90,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
@@ -146,7 +146,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (item.Section == 0)
propVariant = L"Copy";
else if (item.Section < m_Database.Sections.Size())
propVariant = m_Database.Sections[(size_t)item.Section].GetMethodName();
propVariant = m_Database.Sections[(int)item.Section].GetMethodName();
break;
}
case kpidBlock:
@@ -486,7 +486,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
}
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->Init(m_Stream, item.Size);
streamSpec->SetStream(m_Stream);
streamSpec->Init(item.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
@@ -519,7 +520,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
currentTotalSize += item.Size;
continue;
}
const CSectionInfo &section = m_Database.Sections[(size_t)item.Section];
const CSectionInfo &section = m_Database.Sections[(int)item.Section];
if (section.IsLzx())
{
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
@@ -581,7 +582,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if (!testMode && item.Size != 0)
{
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->Init(m_Stream, item.Size);
streamSpec->SetStream(m_Stream);
streamSpec->Init(item.Size);
if(!copyCoder)
copyCoder = new NCompress::CCopyCoder;
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
@@ -592,7 +594,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue;
}
const CSectionInfo &section = m_Database.Sections[(size_t)sectionIndex];
const CSectionInfo &section = m_Database.Sections[(int)sectionIndex];
if (!section.IsLzx())
{
@@ -631,7 +633,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
extractStatuses.Clear();
extractStatuses.Add(true);
for (;true; folderIndex++)
for (;; folderIndex++)
{
RINOK(extractCallback->SetCompleted(&currentTotalSize));
@@ -695,9 +697,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection;
if (rem > rt.BlockSize)
rem = rt.BlockSize;
const UInt64 *offsets = (const UInt64 *)&rt.ResetOffsets.Front();
// const UInt64 *offsets = (const UInt64 *)&rt.ResetOffsets.Front();
RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL));
streamSpec->Init(m_Stream, compressedSize);
streamSpec->SetStream(m_Stream);
streamSpec->Init(compressedSize);
lzxDecoderSpec->SetKeepHistory(b > 0, (int)((offset - startOffset) & 1));
RINOK(lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL));
}
@@ -718,13 +721,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
COM_TRY_BEGIN
*numItems = m_Database.NewFormat ? 1:
(m_Database.LowLevel ?
m_Database.Items.Size():
m_Database.Indices.Size());
return S_OK;
COM_TRY_END
}
}}

View File

@@ -38,7 +38,7 @@ static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
static char GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
static void PrintByte(Byte b, AString &s)
@@ -248,7 +248,8 @@ HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size)
RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
streamSpec->Init(inStream, size);
streamSpec->SetStream(inStream);
streamSpec->Init(size);
_inBuffer.SetStream(limitedStream);
_inBuffer.Init();
return S_OK;
@@ -276,12 +277,12 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
UInt32 unknown1 = ReadUInt32();
if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file
return S_FALSE;
UInt32 timeStamp = ReadUInt32();
/* UInt32 timeStamp = */ ReadUInt32();
// Considered as a big-endian DWORD, it appears to contain seconds (MSB) and
// fractional seconds (second byte).
// The third and fourth bytes may contain even more fractional bits.
// The 4 least significant bits in the last byte are constant.
UInt32 lang = ReadUInt32();
/* UInt32 lang = */ ReadUInt32();
GUID g;
ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC}
ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC}
@@ -319,23 +320,23 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
return S_FALSE;
if (ReadUInt32() != 1) // version
return S_FALSE;
UInt32 dirHeaderSize = ReadUInt32();
/* UInt32 dirHeaderSize = */ ReadUInt32();
ReadUInt32(); // 0x0A (unknown)
UInt32 dirChunkSize = ReadUInt32(); // $1000
if (dirChunkSize < 32)
return S_FALSE;
UInt32 density = ReadUInt32(); // "Density" of quickref section, usually 2.
UInt32 depth = ReadUInt32(); // Depth of the index tree: 1 there is no index,
/* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2.
/* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index,
// 2 if there is one level of PMGI chunks.
UInt32 chunkNumber = ReadUInt32(); // Chunk number of root index chunk, -1 if there is none
/* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none
// (though at least one file has 0 despite there being no
// index chunk, probably a bug.)
UInt32 firstPmglChunkNumber = ReadUInt32(); // Chunk number of first PMGL (listing) chunk
UInt32 lastPmglChunkNumber = ReadUInt32(); // Chunk number of last PMGL (listing) chunk
/* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk
/* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk
ReadUInt32(); // -1 (unknown)
UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total)
UInt32 windowsLangId = ReadUInt32();
/* UInt32 windowsLangId = */ ReadUInt32();
ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC}
ReadUInt32(); // 0x54 (This is the length again)
ReadUInt32(); // -1 (unknown)
@@ -360,7 +361,7 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
ReadUInt32(); // Chunk number of next listing chunk when reading
// directory in sequence (-1 if this is the last listing chunk)
int numItems = 0;
while (true)
for (;;)
{
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
UInt32 offsetLimit = dirChunkSize - quickrefLength;
@@ -448,7 +449,7 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
UInt32 caolLength = ReadUInt32(); // $50 (Length of the CAOL section, which includes the ITSF section)
if (caolLength >= 0x2C)
{
UInt32 c7 = ReadUInt16(); // Unknown. Remains the same when identical files are built.
/* UInt32 c7 = */ ReadUInt16(); // Unknown. Remains the same when identical files are built.
// Does not appear to be a checksum. Many files have
// 'HH' (HTML Help?) here, indicating this may be a compiler ID
// field. But at least one ITOL/ITLS compiler does not set this
@@ -479,13 +480,13 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases;
return S_FALSE;
database.ContentOffset = _startPosition + ReadUInt64();
UInt32 timeStamp = ReadUInt32();
/* UInt32 timeStamp = */ ReadUInt32();
// A timestamp of some sort.
// Considered as a big-endian DWORD, it appears to contain
// seconds (MSB) and fractional seconds (second byte).
// The third and fourth bytes may contain even more fractional
// bits. The 4 least significant bits in the last byte are constant.
UInt32 lang = ReadUInt32(); // BE?
/* UInt32 lang = */ ReadUInt32(); // BE?
}
else
return S_FALSE;
@@ -539,7 +540,7 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
ReadUInt32(); // 0 (unknown)
int numItems = 0;
while (true)
for (;;)
{
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
UInt32 offsetLimit = dirChunkSize - quickrefLength;
@@ -684,7 +685,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
{
// The NameList file
RINOK(DecompressStream(inStream, database, kNameList));
UInt16 length = ReadUInt16();
/* UInt16 length = */ ReadUInt16();
UInt16 numSections = ReadUInt16();
for (int i = 0; i < numSections; i++)
{
@@ -849,7 +850,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
const int kSignatureSize = 8;
UInt64 hxsSignature = NHeader::GetHxsSignature();
UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature;
while(true)
for (;;)
{
Byte b;
if (!_inBuffer.ReadByte(b))

View File

@@ -76,11 +76,11 @@ struct CResetTable
{
if (blockIndex >= ResetOffsets.Size())
return false;
UInt64 startPos = ResetOffsets[(size_t)blockIndex];
UInt64 startPos = ResetOffsets[(int)blockIndex];
if (blockIndex + numBlocks >= ResetOffsets.Size())
size = CompressedSize - startPos;
else
size = ResetOffsets[(size_t)blockIndex + numBlocks] - startPos;
size = ResetOffsets[(int)(blockIndex + numBlocks)] - startPos;
return true;
}
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
@@ -121,7 +121,7 @@ struct CLzxInfo
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
if (blockIndex >= ResetTable.ResetOffsets.Size())
return false;
offset = ResetTable.ResetOffsets[(size_t)blockIndex];
offset = ResetTable.ResetOffsets[(int)blockIndex];
return true;
}
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
@@ -168,7 +168,7 @@ public:
UInt64 GetFolder(int fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
const CSectionInfo &section = Sections[(size_t)item.Section];
const CSectionInfo &section = Sections[(int)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
return 0;
@@ -177,7 +177,7 @@ public:
UInt64 GetLastFolder(int fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
const CSectionInfo &section = Sections[(size_t)item.Section];
const CSectionInfo &section = Sections[(int)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
return 0;

View File

@@ -13,7 +13,7 @@ DEFINE_GUID(CLSID_CChmHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE9, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
{
return TRUE;
}

View File

@@ -127,7 +127,7 @@ struct CBindInfo
class CBindReverseConverter
{
UInt32 _numSrcOutStreams;
const NCoderMixer2::CBindInfo _srcBindInfo;
NCoderMixer2::CBindInfo _srcBindInfo;
CRecordVector<UInt32> _srcInToDestOutMap;
CRecordVector<UInt32> _srcOutToDestInMap;
CRecordVector<UInt32> _destInToSrcOutMap;

View File

@@ -125,7 +125,7 @@ void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes,
static DWORD WINAPI CoderThread(void *threadCoderInfo)
{
while(true)
for (;;)
{
if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode())
return 0;
@@ -137,7 +137,7 @@ static DWORD WINAPI CoderThread(void *threadCoderInfo)
static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
{
while(true)
for (;;)
{
if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode())
return 0;
@@ -282,7 +282,7 @@ bool CCoderMixer2MT::MyCode()
for(int i = 0; i < _coderInfoVector.Size(); i++)
_coderInfoVector[i].CompressEvent->Set();
DWORD result = ::WaitForMultipleObjects(_compressingCompletedEvents.Size(),
/* DWORD result = */ ::WaitForMultipleObjects(_compressingCompletedEvents.Size(),
&_compressingCompletedEvents.Front(), TRUE, INFINITE);
_compressingFinishedEvent.Set();
@@ -292,10 +292,10 @@ bool CCoderMixer2MT::MyCode()
STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
const UInt64 **inSizes,
const UInt64 ** /* inSizes */,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UInt64 **outSizes,
const UInt64 ** /* outSizes */,
UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
@@ -315,7 +315,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
_startCompressingEvent.Set();
while (true)
for (;;)
{
HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent };
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);

View File

@@ -66,7 +66,8 @@ public:
{
{ _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
}
void SetProgressCoderIndex(UInt32 coderIndex)
void SetProgressCoderIndex(UInt32 /*coderIndex*/)
{
// _progressCoderIndex = coderIndex;
}

View File

@@ -37,12 +37,13 @@ HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 siz
STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
RINOK(Init());
UInt32 bufferPos = 0;
if (_outSizeIsDefined = (outSize != 0))
_outSizeIsDefined = (outSize != 0);
if (_outSizeIsDefined)
_outSize = *outSize;
while(NeedMore())

View File

@@ -4,23 +4,25 @@
#include "InStreamWithCRC.h"
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data,
UInt32 size, UInt32 *processedSize)
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (size > 0 && realProcessedSize == 0)
_wasFinished = true;
_crc.Update(data, realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CInStreamWithCRC::Read(void *data,
UInt32 size, UInt32 *processedSize)
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
if (size > 0 && realProcessedSize == 0)
_wasFinished = true;
_size += realProcessedSize;
_crc.Update(data, realProcessedSize);
if(processedSize != NULL)

View File

@@ -19,16 +19,19 @@ private:
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
CCRC _crc;
bool _wasFinished;
public:
void Init(ISequentialInStream *stream)
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
{
_stream = stream;
_size = 0;
_wasFinished = false;
_crc.Init();
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return _crc.GetDigest(); }
UInt64 GetSize() const { return _size; }
bool WasFinished() const { return _wasFinished; }
};
class CInStreamWithCRC:
@@ -44,16 +47,19 @@ private:
CMyComPtr<IInStream> _stream;
UInt64 _size;
CCRC _crc;
bool _wasFinished;
public:
void Init(IInStream *stream)
void SetStream(IInStream *stream) { _stream = stream; }
void Init()
{
_stream = stream;
_size = 0;
_wasFinished = false;
_crc.Init();
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return _crc.GetDigest(); }
UInt64 GetSize() const { return _size; }
bool WasFinished() const { return _wasFinished; }
};
#endif

View File

@@ -40,7 +40,7 @@ bool HasTailSlash(const AString &name, UINT codePage)
return false;
LPCSTR prev =
#ifdef _WIN32
CharPrevExA(codePage, name, &name[name.Length()], 0);
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
#else
(LPCSTR)(name) + (name.Length() - 1);
#endif

View File

@@ -37,8 +37,6 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
UInt64 *newPosition)
{
UInt64 newPos;
if(seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
switch(seekOrigin)
{
case STREAM_SEEK_SET:
@@ -50,6 +48,8 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
case STREAM_SEEK_END:
newPos = _totalLength + offset;
break;
default:
return STG_E_INVALIDFUNCTION;
}
_seekPos = 0;
for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)

View File

@@ -4,8 +4,7 @@
#include "OutStreamWithCRC.h"
STDMETHODIMP COutStreamWithCRC::Write(const void *data,
UInt32 size, UInt32 *processedSize)
STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result;
@@ -16,7 +15,9 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data,
}
else
result = _stream->Write(data, size, &realProcessedSize);
_crc.Update(data, realProcessedSize);
if (_calculateCrc)
_crc.Update(data, realProcessedSize);
_size += realProcessedSize;
if(processedSize != NULL)
*processedSize = realProcessedSize;
return result;

View File

@@ -16,18 +16,22 @@ public:
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
private:
CCRC _crc;
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
CCRC _crc;
bool _calculateCrc;
public:
void Init(ISequentialOutStream *stream)
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void Init(bool calculateCrc = true)
{
_stream = stream;
_size = 0;
_calculateCrc = calculateCrc;
_crc.Init();
}
void ReleaseStream() { _stream.Release(); }
UInt64 GetSize() const { return _size; }
UInt32 GetCRC() const { return _crc.GetDigest(); }
void InitCRC() { _crc.Init(); }
};
#endif

View File

@@ -35,7 +35,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidLastWriteTime, VT_FILETIME}
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -65,19 +65,18 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
bool mustBeClosed = true;
{
CInArchive archive;
if(archive.Open(stream) != S_OK)
@@ -91,7 +90,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
while(true)
for (;;)
{
CItemEx itemInfo;
bool filled;
@@ -217,7 +216,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(_inStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->Init(_inStream, itemInfo.Size);
streamSpec->SetStream(_inStream);
streamSpec->Init(itemInfo.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;

View File

@@ -37,10 +37,21 @@ HRESULT CInArchive::Open(IInStream *inStream)
return S_OK;
}
static void MyStrNCpy(char *dest, const char *src, int size)
{
for (int i = 0; i < size; i++)
{
char c = src[i];
dest[i] = c;
if (c == 0)
break;
}
}
static bool OctalToNumber(const char *s, int size, UInt64 &res)
{
char sz[32];
strncpy(sz, s, size);
MyStrNCpy(sz, s, size);
sz[size] = 0;
const char *end;
int i;
@@ -61,7 +72,7 @@ static bool OctalToNumber32(const char *s, int size, UInt32 &res)
static bool DecimalToNumber(const char *s, int size, UInt64 &res)
{
char sz[32];
strncpy(sz, s, size);
MyStrNCpy(sz, s, size);
sz[size] = 0;
const char *end;
int i;
@@ -96,7 +107,7 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
return S_OK;
char tempString[kNameSize + 1];
strncpy(tempString, cur, kNameSize);
MyStrNCpy(tempString, cur, kNameSize);
cur += kNameSize;
tempString[kNameSize] = '\0';
item.Name = tempString;
@@ -123,7 +134,7 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
{
while(true)
for (;;)
{
RINOK(GetNextItemReal(filled, item));
if (!filled)
@@ -134,7 +145,6 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
return S_OK;
SkeepData(item.Size);
}
return S_OK;
}
HRESULT CInArchive::Skeep(UInt64 numBytes)

View File

@@ -13,9 +13,9 @@ DEFINE_GUID(CLSID_CDebHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEC, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
{
return TRUE;
return TRUE;
}
STDAPI CreateObject(

View File

@@ -85,7 +85,7 @@ STATPROPSTG kProperties[] =
// { L"Is Text", kpidIsText, VT_BOOL},
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -113,21 +113,19 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
COM_TRY_BEGIN
*numItems = 1;
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
@@ -192,8 +190,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
try
@@ -259,7 +257,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLocalProgress *localProgressSpec = new CLocalProgress;
@@ -276,7 +275,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CMyComPtr<ICompressCoder> deflateDecoder;
bool firstItem = true;
RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
while(true)
for (;;)
{
localCompressProgressSpec->Init(progress,
&currentTotalPacked,
@@ -352,10 +351,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if((outStreamSpec->GetCRC() != postItem.FileCRC))
{
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
return S_OK;
break;
}
}
COM_TRY_END
return S_OK;
}
}}

View File

@@ -36,8 +36,7 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
return S_OK;
}
static HRESULT CopyStreams(ISequentialInStream *inStream,
ISequentialOutStream *outStream, IArchiveUpdateCallback *updateCallback)
static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream)
{
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
@@ -56,8 +55,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UInt32 itemIndex = 0;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0,
&newData, &newProperties, &indexInArchive));
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProperties, &indexInArchive));
CItem newItem = m_Item;
newItem.ExtraFlags = 0;
@@ -157,7 +155,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
}
return CopyStreams(m_Stream, outStream, updateCallback);
return CopyStreams(m_Stream, outStream);
}
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)

View File

@@ -55,7 +55,7 @@ HRESULT CInArchive::ReadUInt32(ISequentialInStream *inStream, UInt32 &value)
HRESULT CInArchive::ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc)
{
resString.Empty();
while(true)
for (;;)
{
Byte c;
RINOK(ReadByte(inStream, c));

View File

@@ -48,7 +48,7 @@ HRESULT COutArchive::WriteHeader(const CItem &item)
{
RINOK(WriteUInt16(kSignature));
RINOK(WriteByte(item.CompressionMethod));
RINOK(WriteByte(item.Flags & NFileHeader::NFlags::kNameIsPresent));
RINOK(WriteByte((Byte)(item.Flags & NFileHeader::NFlags::kNameIsPresent)));
RINOK(WriteUInt32(item.Time));
RINOK(WriteByte(item.ExtraFlags));
RINOK(WriteByte(item.HostOS));

View File

@@ -31,7 +31,7 @@ namespace NGZip {
static const Byte kHostOS = NFileHeader::NHostOS::kFAT;
HRESULT UpdateArchive(IInStream *inStream,
HRESULT UpdateArchive(IInStream * /* inStream */,
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CItem &newItem,
@@ -59,7 +59,8 @@ HRESULT UpdateArchive(IInStream *inStream,
CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC;
CMyComPtr<ISequentialInStream> crcStream(inStreamSpec);
inStreamSpec->Init(fileInStream);
inStreamSpec->SetStream(fileInStream);
inStreamSpec->Init();
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;

View File

@@ -13,7 +13,7 @@ DEFINE_GUID(CLSID_CIsoHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE7, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
{
return TRUE;
}

View File

@@ -34,7 +34,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidLastWriteTime, VT_FILETIME}
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -64,18 +64,17 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
bool mustBeClosed = true;
Close();
// try
{
@@ -267,7 +266,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->Init(_inStream, currentItemSize);
streamSpec->SetStream(_inStream);
streamSpec->Init(currentItemSize);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;

View File

@@ -76,7 +76,7 @@ UInt16 CInArchive::ReadUInt16()
throw 1;
value |= ((UInt16)(b[i]) << (8 * i));
}
return value;
return (UInt16)value;
}
UInt32 CInArchive::ReadUInt32Le()
@@ -134,13 +134,13 @@ UInt32 CInArchive::ReadDigits(int numDigits)
void CInArchive::ReadDateTime(CDateTime &d)
{
d.Year = ReadDigits(4);
d.Month = ReadDigits(2);
d.Day = ReadDigits(2);
d.Hour = ReadDigits(2);
d.Minute = ReadDigits(2);
d.Second = ReadDigits(2);
d.Hundredths = ReadDigits(2);
d.Year = (UInt16)ReadDigits(4);
d.Month = (Byte)ReadDigits(2);
d.Day = (Byte)ReadDigits(2);
d.Hour = (Byte)ReadDigits(2);
d.Minute = (Byte)ReadDigits(2);
d.Second = (Byte)ReadDigits(2);
d.Hundredths = (Byte)ReadDigits(2);
d.GmtOffset = (signed char)ReadByte();
}
@@ -254,7 +254,7 @@ void CInArchive::ReadDir(CDir &d, int level)
UInt64 startPos = _position;
bool firstItem = true;
while(true)
for (;;)
{
UInt64 offset = _position - startPos;
if (offset >= d.DataLength)
@@ -311,7 +311,7 @@ void CInArchive::ReadBootInfo()
if (ReadUInt16Spec() != 0)
throw 1;
ReadBytes(e.Id, sizeof(e.Id));
UInt16 checkSum = ReadUInt16Spec();
/* UInt16 checkSum = */ ReadUInt16Spec();
if (ReadByte() != 0x55)
throw 1;
if (ReadByte() != 0xAA)
@@ -346,14 +346,17 @@ HRESULT CInArchive::Open2()
m_BufferPos = 0;
BlockSize = kBlockSize;
VolDescs.Add(CVolumeDescriptor());
while(true)
for (;;)
{
Byte sig[6];
ReadBytes(sig, 6);
if (!CheckDescriptorSignature(sig + 1))
return S_FALSE;
if (ReadByte() != kVersion)
throw 1;
// version = 2 for ISO 9660:1999?
Byte ver = ReadByte();
if (ver > 2)
throw S_FALSE;
if (sig[0] == NVolDescType::kTerminator)
break;
switch(sig[0])

View File

@@ -36,7 +36,7 @@ struct CDir: public CDirRecord
int GetLengthU() const
{
int len = FileId.GetCapacity() / 2;
int len = (int)(FileId.GetCapacity() / 2);
if (Parent != 0)
if (Parent->Parent != 0)
len += 1 + Parent->GetLengthU();
@@ -51,7 +51,7 @@ struct CDir: public CDirRecord
p += len;
*p = 0;
const CDir *cur = this;
while(true)
for (;;)
{
int curLen = cur->GetLengthCur(checkSusp, skipSize);
p -= curLen;
@@ -76,15 +76,15 @@ struct CDir: public CDirRecord
p += len;
*p = 0;
const CDir *cur = this;
while(true)
for (;;)
{
int curLen = cur->FileId.GetCapacity() / 2;
int curLen = (int)(cur->FileId.GetCapacity() / 2);
p -= curLen;
for (int i = 0; i < curLen; i++)
{
Byte b0 = ((const Byte *)cur->FileId)[i * 2];
Byte b1 = ((const Byte *)cur->FileId)[i * 2 + 1];
p[i] = ((wchar_t)b0 << 8) | (wchar_t)b1;
p[i] = (wchar_t)(((wchar_t)b0 << 8) | b1);
}
cur = cur->Parent;
if (cur == 0)

View File

@@ -25,7 +25,7 @@ struct CRecordingDateTime
bool GetFileTime(FILETIME &ft) const
{
SYSTEMTIME st;
st.wYear = Year + 1900;
st.wYear = (WORD)(Year + 1900);
st.wMonth = Month;
st.wDayOfWeek = 0; // check it
st.wDay = Day;
@@ -69,7 +69,7 @@ struct CDirRecord
{
lenRes = 0;
const Byte *p = (const Byte *)SystemUse + skipSize;
int length = SystemUse.GetCapacity() - skipSize;
int length = (int)(SystemUse.GetCapacity() - skipSize);
while (length >= 5)
{
int len = p[2];
@@ -93,7 +93,7 @@ struct CDirRecord
if (res != 0)
return len;
}
return FileId.GetCapacity();
return (int)FileId.GetCapacity();
}
const Byte* GetNameCur(bool checkSusp, int skipSize) const
@@ -127,7 +127,7 @@ struct CDirRecord
bool CheckSusp(int &startPos) const
{
const Byte *p = (const Byte *)SystemUse;
int length = SystemUse.GetCapacity();
int length = (int)SystemUse.GetCapacity();
const int kMinLen = 7;
if (length < kMinLen)
return false;

View File

@@ -13,7 +13,7 @@ DEFINE_GUID(CLSID_CLzhHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
{
return TRUE;
}

View File

@@ -36,7 +36,7 @@ void CCRC::Update(const void *data, size_t size)
UInt16 v = _value;
const Byte *p = (const Byte *)data;
for (; size > 0; size--, p++)
v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
v = (UInt16)(Table[((Byte)(v)) ^ *p] ^ (v >> 8));
_value = v;
}

View File

@@ -11,7 +11,7 @@ namespace NLzh {
class CCRC
{
UInt32 _value;
UInt16 _value;
public:
static UInt16 Table[256];
static void InitTable();

View File

@@ -89,7 +89,7 @@ STATPROPSTG kProperties[] =
CHandler::CHandler()
{}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -119,8 +119,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
@@ -226,7 +226,7 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
*/
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback)
{
COM_TRY_BEGIN
try
@@ -240,7 +240,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
UInt64 numFiles = _items.Size();
RINOK(callback->SetCompleted(&numFiles, NULL));
}
while(true)
for (;;)
{
CItemEx itemInfo;
bool filled;
@@ -307,7 +307,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
UInt64 currentItemUnPacked, currentItemPacked;
NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec;
NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0;
CMyComPtr<ICompressCoder> lzhDecoder;
CMyComPtr<ICompressCoder> lzh1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder;
@@ -357,7 +357,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 pos;
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
streamSpec->Init(_stream, itemInfo.PackSize);
streamSpec->SetStream(_stream);
streamSpec->Init(itemInfo.PackSize);
CLocalProgress *localProgressSpec = new CLocalProgress;

View File

@@ -66,9 +66,9 @@ static const Byte *ReadString(const Byte *p, size_t size, AString &s)
static Byte CalcSum(const Byte *data, size_t size)
{
Byte sum = 0;
for (size_t i = 0; i < size; i++)
sum += data[i];
return sum;
for (size_t i = 0; i < size; i++)
sum = (Byte)(sum + data[i]);
return sum;
}
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)

View File

@@ -150,7 +150,7 @@ public:
AString GetName() const
{
AString dirName = GetDirName();
dirName.Replace((char)0xFF, '\\');
dirName.Replace((char)(unsigned char)0xFF, '\\');
if (!dirName.IsEmpty())
{
char c = dirName[dirName.Length() - 1];

View File

@@ -42,7 +42,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidSolid, VT_BOOL}
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -71,15 +71,15 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback)
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
bool mustBeClosed = true;
Close();
{
if(_archive.Open(stream, maxCheckStartPosition) != S_OK)

View File

@@ -53,7 +53,7 @@ void CInArchive::ReadBlockHeader(CBlockHeader &bh)
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
static int CompareItems(void *const *p1, void *const *p2, void *param)
static int CompareItems(void *const *p1, void *const *p2, void * /* param */)
{
RINOZ(MyCompare(
(**(const CItem **)p1).Pos,
@@ -65,17 +65,19 @@ AString CInArchive::ReadString(UInt32 pos)
{
AString s;
UInt32 offset = GetOffset() + _stringsPos + pos;
while(true)
for (;;)
{
if (offset >= _size)
throw 1;
char c = _data[offset++];
if (c == 0)
return s;
break;
s += c;
}
return s;
}
/*
static AString ParsePrefix(const AString &prefix)
{
AString res = prefix;
@@ -88,7 +90,7 @@ static AString ParsePrefix(const AString &prefix)
}
return res;
}
*/
#define SYSREGKEY "Software\\Microsoft\\Windows\\CurrentVersion"
@@ -525,13 +527,19 @@ AString CInArchive::ReadString2(UInt32 pos)
#define DEL_REBOOT 4
// #define DEL_SIMPLE 8
const int kNumEntryParams = 6;
static const int kNumEntryParams = 6;
struct CEntry
{
UInt32 Which;
UInt32 Params[kNumEntryParams];
AString GetParamsString(int numParams);
CEntry()
{
Which = 0;
for (UInt32 j = 0; j < kNumEntryParams; j++)
Params[j] = 0;
}
};
AString CEntry::GetParamsString(int numParams)
@@ -584,12 +592,12 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{
CItem item;
item.Prefix = prefix;
UInt32 overwriteFlag = e.Params[0];
/* UInt32 overwriteFlag = e.Params[0]; */
item.Name = ReadString2(e.Params[1]);
item.Pos = e.Params[2];
item.DateTime.dwLowDateTime = e.Params[3];
item.DateTime.dwHighDateTime = e.Params[4];
UInt32 allowIgnore = e.Params[5];
/* UInt32 allowIgnore = e.Params[5]; */
if (Items.Size() > 0)
{
/*
@@ -949,7 +957,7 @@ HRESULT CInArchive::Parse()
{
// UInt32 offset = ReadUInt32();
// ???? offset == FirstHeader.HeaderLength
UInt32 ehFlags = ReadUInt32();
/* UInt32 ehFlags = */ ReadUInt32();
CBlockHeader bhPages, bhSections, bhEntries, bhStrings, bhLangTables, bhCtlColors, bhData;
// CBlockHeader bgFont;
ReadBlockHeader(bhPages);
@@ -1034,7 +1042,8 @@ HRESULT CInArchive::Open2()
_posInData = 0;
if (!IsSolid)
{
if (_headerIsCompressed = ((compressedHeaderSize & 0x80000000) != 0))
_headerIsCompressed = ((compressedHeaderSize & 0x80000000) != 0);
if (_headerIsCompressed)
compressedHeaderSize &= ~0x80000000;
_nonSolidStartOffset = compressedHeaderSize;
RINOK(_stream->Seek(StreamOffset + 4, STREAM_SEEK_SET, NULL));
@@ -1113,7 +1122,7 @@ HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPositio
Byte buffer[kStep];
bool found = false;
UInt64 headerPosition;
UInt64 headerPosition = 0;
while (position <= maxSize)
{
UInt32 processedSize;

View File

@@ -13,9 +13,9 @@ DEFINE_GUID(CLSID_CRpmHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEB, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
{
return TRUE;
return TRUE;
}
STDAPI CreateObject(

View File

@@ -33,7 +33,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidPackedSize, VT_UI8}
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -63,15 +63,15 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
try
@@ -104,7 +104,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;

View File

@@ -16,7 +16,7 @@ namespace NRpm {
static UInt16 GetUInt16(const char *data)
{
return (Byte)data[1] | (((UInt16)(Byte)data[0]) << 8);
return (UInt16)((Byte)data[1] | (((UInt16)(Byte)data[0]) << 8));
}
static UInt32 GetUInt32(const char *data)

View File

@@ -351,14 +351,6 @@ SOURCE=..\..\Crypto\RarAES\RarAES.cpp
SOURCE=..\..\Crypto\RarAES\RarAES.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\RarAES\sha1.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\RarAES\sha1.h
# End Source File
# End Group
# Begin Group "Rar20"
@@ -380,6 +372,28 @@ SOURCE=..\..\Crypto\Rar20\Rar20Crypto.cpp
SOURCE=..\..\Crypto\Rar20\Rar20Crypto.h
# End Source File
# End Group
# Begin Group "Hash"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Crypto\Hash\Sha1.cpp
!IF "$(CFG)" == "Rar - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Rar - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\Sha1.h
# End Source File
# End Group
# End Group
# Begin Group "7-zip Common"

View File

@@ -360,7 +360,6 @@ public:
}
int numLetters = 1;
bool splitStyle = false;
if (basePart.Right(numLetters) == L"1")
{
while (numLetters < basePart.Length())
@@ -432,7 +431,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
}
while(true)
for (;;)
{
CMyComPtr<IInStream> inStream;
if (!_archives.IsEmpty())
@@ -475,7 +474,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
archive.GetArchiveInfo(_archiveInfo);
CItemEx item;
while(true)
for (;;)
{
HRESULT result = archive.GetNextItem(item, getTextPassword);
if (result == S_FALSE)
@@ -618,9 +617,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CFilterCoder *filterStreamSpec = new CFilterCoder;
CMyComPtr<ISequentialInStream> filterStream = filterStreamSpec;
NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec;
NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec = NULL;
CMyComPtr<ICompressFilter> rar20CryptoDecoder;
NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec;
NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec = NULL;
CMyComPtr<ICompressFilter> rar29CryptoDecoder;
CFolderInStream *folderInStreamSpec = NULL;
@@ -681,7 +680,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
UInt64 packedPos = currentImportantTotalPacked;
@@ -866,8 +866,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2,
&compressSetDecoderProperties));
Byte isSolid =
(IsSolid(index) || item.IsSplitBefore()) ? 1: 0;
Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0);
RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1));

View File

@@ -72,16 +72,16 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
UInt32 numBytesPrev = NHeader::kMarkerSize - 1;
memmove(buffer, marker + 1, numBytesPrev);
UInt64 curTestPos = m_StreamStartPosition + 1;
while(true)
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
return false;
break;
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
if (numBytesInBuffer < NHeader::kMarkerSize)
return false;
break;
UInt32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1;
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
{
@@ -174,7 +174,6 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
crc.UpdateByte(m_ArchiveHeader.EncryptVersion);
}
UInt32 u = crc.GetDigest();
if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF))
ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError);
if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader)
@@ -197,7 +196,7 @@ void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
archiveInfo.StartPosition = m_ArchiveStartPosition;
archiveInfo.Flags = m_ArchiveHeader.Flags;
archiveInfo.CommentPosition = m_ArchiveCommentPosition;
archiveInfo.CommentSize = m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize;
archiveInfo.CommentSize = (UInt16)(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize);
}
static void DecodeUnicodeFileName(const char *name, const Byte *encName,
@@ -221,10 +220,10 @@ static void DecodeUnicodeFileName(const char *name, const Byte *encName,
unicodeName[decPos++] = encName[encPos++];
break;
case 1:
unicodeName[decPos++] = encName[encPos++] + (highByte << 8);
unicodeName[decPos++] = (wchar_t)(encName[encPos++] + (highByte << 8));
break;
case 2:
unicodeName[decPos++] = encName[encPos] + (encName[encPos + 1] << 8);
unicodeName[decPos++] = (wchar_t)(encName[encPos] + (encName[encPos + 1] << 8));
encPos += 2;
break;
case 3:
@@ -235,7 +234,7 @@ static void DecodeUnicodeFileName(const char *name, const Byte *encName,
Byte correction = encName[encPos++];
for (length = (length & 0x7f) + 2;
length > 0 && decPos < maxDecSize; length--, decPos++)
unicodeName[decPos] = ((name[decPos] + correction) & 0xff) + (highByte << 8);
unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8));
}
else
for (length += 2; length > 0 && decPos < maxDecSize; length--, decPos++)
@@ -316,7 +315,7 @@ UInt32 CInArchive::ReadUInt32()
void CInArchive::ReadTime(Byte mask, CRarTime &rarTime)
{
rarTime.LowSecond = ((mask & 4) != 0) ? 1 : 0;
rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0);
int numDigits = (mask & 3);
rarTime.SubTime[0] = rarTime.SubTime[1] = rarTime.SubTime[2] = 0;
for (int i = 0; i < numDigits; i++)
@@ -353,20 +352,23 @@ void CInArchive::ReadHeaderReal(CItemEx &item)
for (int i = 0; i < sizeof(item.Salt); i++)
item.Salt[i] = ReadByte();
if (item.HasExtTime())
// some rar archives have HasExtTime flag without field.
if (m_CurPos < m_PosLimit && item.HasExtTime())
{
Byte accessMask = ReadByte() >> 4;
Byte accessMask = (Byte)(ReadByte() >> 4);
Byte b = ReadByte();
Byte modifMask = b >> 4;
Byte createMask = b & 0xF;
Byte modifMask = (Byte)(b >> 4);
Byte createMask = (Byte)(b & 0xF);
if ((modifMask & 8) != 0)
ReadTime(modifMask, item.LastWriteTime);
if (item.IsCreationTimeDefined = ((createMask & 8) != 0))
item.IsCreationTimeDefined = ((createMask & 8) != 0);
if (item.IsCreationTimeDefined)
{
item.CreationTime.DosTime = ReadUInt32();
ReadTime(createMask, item.CreationTime);
}
if (item.IsLastAccessTimeDefined = ((accessMask & 8) != 0))
item.IsLastAccessTimeDefined = ((accessMask & 8) != 0);
if (item.IsLastAccessTimeDefined)
{
item.LastAccessTime.DosTime = ReadUInt32();
ReadTime(accessMask, item.LastAccessTime);
@@ -377,10 +379,10 @@ void CInArchive::ReadHeaderReal(CItemEx &item)
item.Position = m_Position;
item.MainPartSize = fileHeaderWithNameSize;
item.CommentSize = m_BlockHeader.HeadSize - fileHeaderWithNameSize;
item.CommentSize = (UInt16)(m_BlockHeader.HeadSize - fileHeaderWithNameSize);
if (m_CryptoMode)
item.AlignSize = (16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF;
item.AlignSize = (UInt16)((16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF);
else
item.AlignSize = 0;
AddToSeekValue(m_BlockHeader.HeadSize);
@@ -395,7 +397,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
{
if (m_SeekOnArchiveComment)
SkipArchiveComment();
while (true)
for (;;)
{
if(!SeekInArchive(m_Position))
return S_FALSE;
@@ -525,7 +527,8 @@ ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 siz
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
SeekInArchive(position);
streamSpec->Init(m_Stream, size);
streamSpec->SetStream(m_Stream);
streamSpec->Init(size);
return inStream.Detach();
}

View File

@@ -44,7 +44,17 @@ UInt32 CItem::GetDictSize() const
bool CItem::IsDirectory() const
{
return (GetDictSize() == NHeader::NFile::kDictDirectoryValue);
if (GetDictSize() == NHeader::NFile::kDictDirectoryValue)
return true;
switch(HostOS)
{
case NHeader::NFile::kHostMSDOS:
case NHeader::NFile::kHostOS2:
case NHeader::NFile::kHostWin32:
if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
return true;
}
return false;
}
UInt32 CItem::GetWinAttributes() const
@@ -68,41 +78,41 @@ UInt32 CItem::GetWinAttributes() const
void CItem::ClearFlags()
{ Flags = 0; }
void CItem::SetFlagBits(int aStartBitNumber, int aNumBits, int aValue)
void CItem::SetFlagBits(int startBitNumber, int numBits, int value)
{
UInt16 mask = ((1 << aNumBits) - 1) << aStartBitNumber;
UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber);
Flags &= ~mask;
Flags |= aValue << aStartBitNumber;
Flags |= value << startBitNumber;
}
void CItem::SetBitMask(int aBitMask, bool anEnable)
void CItem::SetBitMask(int bitMask, bool enable)
{
if(anEnable)
Flags |= aBitMask;
if(enable)
Flags |= bitMask;
else
Flags &= ~aBitMask;
Flags &= ~bitMask;
}
void CItem::SetDictSize(UInt32 aSize)
void CItem::SetDictSize(UInt32 size)
{
SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (aSize & NHeader::NFile::kDictMask));
SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (size & NHeader::NFile::kDictMask));
}
void CItem::SetAsDirectory(bool aDirectory)
void CItem::SetAsDirectory(bool directory)
{
if (aDirectory)
if (directory)
SetDictSize(NHeader::NFile::kDictDirectoryValue);
}
void CItem::SetEncrypted(bool anEncrypted)
{ SetBitMask(NHeader::NFile::kEncrypted, anEncrypted); }
void CItem::SetSolid(bool aSolid)
{ SetBitMask(NHeader::NFile::kSolid, aSolid); }
void CItem::SetCommented(bool aCommented)
{ SetBitMask(NHeader::NFile::kComment, aCommented); }
void CItem::SetSplitBefore(bool aSplitBefore)
{ SetBitMask(NHeader::NFile::kSplitBefore, aSplitBefore); }
void CItem::SetSplitAfter(bool aSplitAfter)
{ SetBitMask(NHeader::NFile::kSplitAfter, aSplitAfter); }
void CItem::SetEncrypted(bool encrypted)
{ SetBitMask(NHeader::NFile::kEncrypted, encrypted); }
void CItem::SetSolid(bool solid)
{ SetBitMask(NHeader::NFile::kSolid, solid); }
void CItem::SetCommented(bool commented)
{ SetBitMask(NHeader::NFile::kComment, commented); }
void CItem::SetSplitBefore(bool splitBefore)
{ SetBitMask(NHeader::NFile::kSplitBefore, splitBefore); }
void CItem::SetSplitAfter(bool splitAfter)
{ SetBitMask(NHeader::NFile::kSplitAfter, splitAfter); }
}}

View File

@@ -58,17 +58,17 @@ public:
CItem(): IsCreationTimeDefined(false), IsLastAccessTimeDefined(false) {}
private:
void SetFlagBits(int aStartBitNumber, int aNumBits, int aValue);
void SetBitMask(int aBitMask, bool anEnable);
void SetFlagBits(int startBitNumber, int numBits, int value);
void SetBitMask(int bitMask, bool enable);
public:
void ClearFlags();
void SetDictSize(UInt32 aSize);
void SetAsDirectory(bool aDirectory);
void SetEncrypted(bool anEncrypted);
void SetSolid(bool aSolid);
void SetCommented(bool aCommented);
void SetSplitBefore(bool aSplitBefore);
void SetSplitAfter(bool aSplitAfter);
void SetDictSize(UInt32 size);
void SetAsDirectory(bool directory);
void SetEncrypted(bool encrypted);
void SetSolid(bool solid);
void SetCommented(bool commented);
void SetSplitBefore(bool splitBefore);
void SetSplitAfter(bool splitAfter);
};
class CItemEx: public CItem

View File

@@ -42,13 +42,15 @@ AR_COMMON_OBJS = \
$O\7zMethodID.obj \
$O\7zMethods.obj \
CRYPTO_HASH_OBJS = \
$O\Sha1.obj \
CRYPTO_RAR20_OBJS = \
$O\Rar20Cipher.obj \
$O\Rar20Crypto.obj \
CRYPTO_RARAES_OBJS = \
$O\RarAES.obj \
$O\sha1.obj \
OBJS = \
$O\StdAfx.obj \
@@ -58,6 +60,7 @@ OBJS = \
$(7ZIP_COMMON_OBJS) \
$(AR_COMMON_OBJS) \
$(7Z_OBJS) \
$(CRYPTO_HASH_OBJS) \
$(CRYPTO_RAR20_OBJS) \
$(CRYPTO_RARAES_OBJS) \
$O\CopyCoder.obj \
@@ -77,6 +80,8 @@ $(AR_COMMON_OBJS): ../Common/$(*B).cpp
$(COMPL)
$(7Z_OBJS): ../7z/$(*B).cpp
$(COMPL)
$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
$(COMPL_O2)
$(CRYPTO_RAR20_OBJS): ../../Crypto/Rar20/$(*B).cpp
$(COMPL)
$(CRYPTO_RARAES_OBJS): ../../Crypto/RarAES/$(*B).cpp

View File

@@ -13,9 +13,9 @@ DEFINE_GUID(CLSID_CSplitHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEA, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
{
return TRUE;
return TRUE;
}
STDAPI CreateObject(

View File

@@ -31,7 +31,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidPackedSize, VT_UI8},
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -61,8 +61,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
@@ -142,7 +142,7 @@ public:
};
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
@@ -235,7 +235,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
while (true)
for (;;)
{
UString fullName = seqName.GetNextName();
CMyComPtr<IInStream> nextStream;
@@ -286,7 +286,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;

View File

@@ -13,7 +13,7 @@ DEFINE_GUID(CLSID_CTarHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEE, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
{
return TRUE;
}

View File

@@ -36,7 +36,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidGroup, VT_BSTR},
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -66,14 +66,14 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
@@ -93,7 +93,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
while(true)
for (;;)
{
CItemEx item;
bool filled;
@@ -242,7 +242,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->Init(_inStream, item.Size);
streamSpec->SetStream(_inStream);
streamSpec->Init(item.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;

View File

@@ -12,6 +12,7 @@ namespace NFileHeader {
const char *kCheckSumBlanks = " "; // 8 blanks, no null
const char *kLongLink = "././@LongLink";
const char *kLongLink2 = "@LongLink";
// The magic field is filled with this if uname and gname are valid.
namespace NMagic

View File

@@ -81,7 +81,8 @@ namespace NFileHeader
// The checksum field is filled with this while the checksum is computed.
extern const char *kCheckSumBlanks;// = " "; // 8 blanks, no null
extern const char *kLongLink; // = "././@LongLink";
extern const char *kLongLink; // = "././@LongLink";
extern const char *kLongLink2; // = "@LongLink";
// The magic field is filled with this if uname and gname are valid.
namespace NMagic

View File

@@ -27,10 +27,21 @@ HRESULT CInArchive::Open(IInStream *inStream)
return S_OK;
}
static void MyStrNCpy(char *dest, const char *src, int size)
{
for (int i = 0; i < size; i++)
{
char c = src[i];
dest[i] = c;
if (c == 0)
break;
}
}
static bool OctalToNumber(const char *srcString, int size, UInt64 &res)
{
char sz[32];
strncpy(sz, srcString, size);
MyStrNCpy(sz, srcString, size);
sz[size] = 0;
const char *end;
int i;
@@ -63,14 +74,14 @@ static void ReadString(const char *s, int size, AString &result)
if (size > NFileHeader::kRecordSize)
size = NFileHeader::kNameSize;
char tempString[NFileHeader::kRecordSize + 1];
strncpy(tempString, s, size);
MyStrNCpy(tempString, s, size);
tempString[size] = '\0';
result = tempString;
}
static char GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
@@ -109,8 +120,8 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
if (((Byte)c) < 0x20)
{
item.Name += '[';
item.Name += GetHex(((Byte)c) >> 4);
item.Name += GetHex(((Byte)c) & 0xF);
item.Name += GetHex((Byte)(((Byte)c) >> 4));
item.Name += GetHex((Byte)(((Byte)c) & 0xF));
item.Name += ']';
}
else
@@ -190,7 +201,8 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
if (item.LinkFlag == 'L')
{
if (item.Name.Compare(NFileHeader::kLongLink) != 0)
return S_FALSE;
if (item.Name.Compare(NFileHeader::kLongLink2) != 0)
return S_FALSE;
UInt64 headerPosition = item.HeaderPosition;
UInt32 processedSize;

View File

@@ -33,6 +33,17 @@ static AString MakeOctalString(UInt64 value)
return AString(s) + ' ';
}
static void MyStrNCpy(char *dest, const char *src, int size)
{
for (int i = 0; i < size; i++)
{
char c = src[i];
dest[i] = c;
if (c == 0)
break;
}
}
static bool MakeOctalString8(char *s, UInt32 value)
{
AString tempString = MakeOctalString(value);
@@ -43,7 +54,7 @@ static bool MakeOctalString8(char *s, UInt32 value)
int numSpaces = kMaxSize - (tempString.Length() + 1);
for(int i = 0; i < numSpaces; i++)
s[i] = ' ';
strcpy(s + numSpaces, tempString);
MyStringCopy(s + numSpaces, (const char *)tempString);
return true;
}
@@ -64,7 +75,7 @@ static bool CopyString(char *dest, const AString &src, int maxSize)
{
if (src.Length() >= maxSize)
return false;
strcpy(dest, src);
MyStringCopy(dest, (const char *)src);
return true;
}
@@ -81,7 +92,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
// RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize));
if (item.Name.Length() > NFileHeader::kNameSize)
return E_FAIL;
strncpy(cur, item.Name, NFileHeader::kNameSize);
MyStrNCpy(cur, item.Name, NFileHeader::kNameSize);
cur += NFileHeader::kNameSize;
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.Mode));

View File

@@ -139,13 +139,15 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
RINOK(outArchive.WriteHeader(item));
RINOK(inStream->Seek(existItemInfo.GetDataPosition(),
STREAM_SEEK_SET, NULL));
streamSpec->Init(inStream, existItemInfo.Size);
streamSpec->SetStream(inStream);
streamSpec->Init(existItemInfo.Size);
}
else
{
RINOK(inStream->Seek(existItemInfo.HeaderPosition,
STREAM_SEEK_SET, NULL));
streamSpec->Init(inStream, existItemInfo.GetFullSize());
streamSpec->SetStream(inStream);
streamSpec->Init(existItemInfo.GetFullSize());
}
RINOK(CopyBlock(inStreamLimited, outStream, compressProgress));
RINOK(outArchive.FillDataResidual(existItemInfo.Size));

View File

@@ -12,13 +12,9 @@
DEFINE_GUID(CLSID_CZHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
HINSTANCE g_hInstance;
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
{
if (dwReason == DLL_PROCESS_ATTACH)
g_hInstance = hInstance;
return TRUE;
}

View File

@@ -25,7 +25,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidPackedSize, VT_UI8},
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -55,8 +55,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
}
@@ -90,8 +90,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
static const int kSignatureSize = 3;
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
try

View File

@@ -8,6 +8,8 @@
#include "Windows/PropVariant.h"
#include "../../ICoder.h"
#include "../../IPassword.h"
#include "../../Crypto/WzAES/WzAES.h"
#include "../Common/CodecsPath.h"
// {23170F69-40C1-278B-0401-080000000100}
DEFINE_GUID(CLSID_CCompressDeflateEncoder,
@@ -62,6 +64,12 @@ static bool IsItWindowsNT()
}
#endif
void GetCryptoFolderPrefix(TCHAR *path)
{
CSysString s = GetCodecsFolderPrefix();
lstrcpy(path, s);
}
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{

View File

@@ -142,6 +142,14 @@ SOURCE=..\..\..\Common\CRC.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File
# Begin Source File
@@ -216,6 +224,18 @@ SOURCE=..\..\..\Windows\PropVariant.cpp
SOURCE=..\..\..\Windows\PropVariant.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Thread.h
# End Source File
# End Group
# Begin Group "Archive Common"
@@ -306,6 +326,14 @@ SOURCE=..\..\Common\LSBFDecoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\MemBlocks.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\MemBlocks.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\OffsetStream.cpp
# End Source File
# Begin Source File
@@ -322,6 +350,22 @@ SOURCE=..\..\Common\OutBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutMemStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutMemStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressMt.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressMt.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressUtils.cpp
# End Source File
# Begin Source File
@@ -420,6 +464,88 @@ SOURCE=.\ZipUpdate.h
# Begin Group "Crypto"
# PROP Default_Filter ""
# Begin Group "WzAes"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Crypto\WzAES\WzAES.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\WzAES\WzAES.h
# End Source File
# End Group
# Begin Group "Hash"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Crypto\Hash\HmacSha1.cpp
!IF "$(CFG)" == "Zip - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Zip - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\HmacSha1.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.cpp
!IF "$(CFG)" == "Zip - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Zip - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\RandGen.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\RandGen.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\RotateDefs.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\Sha1.cpp
!IF "$(CFG)" == "Zip - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Zip - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Hash\Sha1.h
# End Source File
# End Group
# Begin Source File
SOURCE=..\..\Crypto\Zip\ZipCipher.cpp

View File

@@ -7,6 +7,7 @@
#include "Windows/Defs.h"
#include "../../ICoder.h"
#include "../../IPassword.h"
#include "../Common/InStreamWithCRC.h"
#include "../7z/7zMethods.h"
#include "ZipAddCommon.h"
@@ -48,9 +49,6 @@ DEFINE_GUID(CLSID_CCryptoZipEncoder,
namespace NArchive {
namespace NZip {
static const Byte kMethodIDForEmptyStream = NFileHeader::NCompressionMethod::kStored;
static const Byte kExtractVersionForEmptyStream = NFileHeader::NCompressionMethod::kStoreExtractVersion;
CAddCommon::CAddCommon(const CCompressionMethodMode &options):
_options(options),
_copyCoderSpec(NULL),
@@ -63,7 +61,7 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
crc.Init();
const UInt32 kBufferSize = (1 << 14);
Byte buffer[kBufferSize];
while(true)
for (;;)
{
UInt32 realProcessedSize;
RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));
@@ -77,36 +75,47 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
}
HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStream,
UInt64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult)
ICompressProgressInfo *progress, CCompressingResult &operationResult)
{
/*
if(inSize == 0)
CSequentialInStreamWithCRC *inSecCrcStreamSpec = 0;
CInStreamWithCRC *inCrcStreamSpec = 0;
CMyComPtr<ISequentialInStream> inCrcStream;
{
operationResult.PackSize = 0;
operationResult.Method = kMethodIDForEmptyStream;
operationResult.ExtractVersion = kExtractVersionForEmptyStream;
return S_OK;
CMyComPtr<IInStream> inStream2;
// we don't support stdin, since stream from stdin can require 64-bit size header
RINOK(inStream->QueryInterface(IID_IInStream, (void **)&inStream2));
if (inStream2)
{
inCrcStreamSpec = new CInStreamWithCRC;
inCrcStream = inCrcStreamSpec;
inCrcStreamSpec->SetStream(inStream2);
inCrcStreamSpec->Init();
}
else
{
inSecCrcStreamSpec = new CSequentialInStreamWithCRC;
inCrcStream = inSecCrcStreamSpec;
inSecCrcStreamSpec->SetStream(inStream);
inSecCrcStreamSpec->Init();
}
}
*/
CMyComPtr<IInStream> inStream2;
int numTestMethods = _options.MethodSequence.Size();
if (numTestMethods > 1 || _options.PasswordIsDefined)
{
inStream->QueryInterface(IID_IInStream, (void **)&inStream2);
if (!inStream2)
if (inCrcStreamSpec == 0)
{
if (_options.PasswordIsDefined)
return E_NOTIMPL;
numTestMethods = 1;
}
}
Byte method;
UInt64 resultSize = 0;
Byte method = 0;
COutStreamReleaser outStreamReleaser;
for(int i = 0; i < numTestMethods; i++)
{
if (inStream2)
RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
if (inCrcStreamSpec != 0)
RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
if (_options.PasswordIsDefined)
{
@@ -114,18 +123,28 @@ HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStrea
{
_cryptoStreamSpec = new CFilterCoder;
_cryptoStream = _cryptoStreamSpec;
_filterSpec = new NCrypto::NZip::CEncoder;
_cryptoStreamSpec->Filter = _filterSpec;
}
RINOK(_filterSpec->CryptoSetPassword(
(const Byte *)(const char *)_options.Password, _options.Password.Length()));
UInt32 crc;
RINOK(GetStreamCRC(inStream, crc));
RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
if (_options.IsAesMode)
{
_cryptoStreamSpec->Filter = _aesFilter = _filterAesSpec = new NCrypto::NWzAES::CEncoder;
_filterAesSpec->SetKeyMode(_options.AesKeyMode);
RINOK(_filterAesSpec->CryptoSetPassword(
(const Byte *)(const char *)_options.Password, _options.Password.Length()));
RINOK(_filterAesSpec->WriteHeader(outStream));
}
else
{
_cryptoStreamSpec->Filter = _zipCryptoFilter = _filterSpec = new NCrypto::NZip::CEncoder;
RINOK(_filterSpec->CryptoSetPassword(
(const Byte *)(const char *)_options.Password, _options.Password.Length()));
UInt32 crc = 0;
RINOK(GetStreamCRC(inStream, crc));
RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
RINOK(_filterSpec->CryptoSetCRC(crc));
RINOK(_filterSpec->WriteHeader(outStream));
}
RINOK(_cryptoStreamSpec->SetOutStream(outStream));
outStreamReleaser.FilterCoder = _cryptoStreamSpec;
RINOK(_filterSpec->CryptoSetCRC(crc));
RINOK(_filterSpec->WriteHeader(outStream));
}
method = _options.MethodSequence[i];
@@ -143,8 +162,7 @@ HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStrea
outStreamNew = _cryptoStream;
else
outStreamNew = outStream;
RINOK(_copyCoder->Code(inStream, outStreamNew,
NULL, NULL, progress));
RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kStoreExtractVersion;
break;
}
@@ -251,24 +269,41 @@ HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStrea
outStreamNew = _cryptoStream;
else
outStreamNew = outStream;
RINOK(_compressEncoder->Code(inStream, outStreamNew, NULL, NULL, progress));
RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion;
break;
}
}
outStream->Seek(0, STREAM_SEEK_CUR, &resultSize);
RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &operationResult.PackSize));
if (inCrcStreamSpec != 0)
{
operationResult.CRC = inCrcStreamSpec->GetCRC();
operationResult.UnpackSize = inCrcStreamSpec->GetSize();
}
else
{
operationResult.CRC = inSecCrcStreamSpec->GetCRC();
operationResult.UnpackSize = inSecCrcStreamSpec->GetSize();
}
if (_options.PasswordIsDefined)
{
if(resultSize < inSize + 12)
if (operationResult.PackSize < operationResult.UnpackSize +
(_options.IsAesMode ? _filterAesSpec->GetHeaderSize() : NCrypto::NZip::kHeaderSize))
break;
}
else if(resultSize < inSize)
else if (operationResult.PackSize < operationResult.UnpackSize)
break;
}
RINOK(outStream->SetSize(resultSize));
operationResult.PackSize = resultSize;
if (_options.IsAesMode)
{
RINOK(_filterAesSpec->WriteFooter(outStream));
RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &operationResult.PackSize));
}
operationResult.Method = method;
return S_OK;
return outStream->SetSize(operationResult.PackSize);
}
}}

View File

@@ -12,14 +12,17 @@
#include "../Common/FilterCoder.h"
#include "ZipCompressionMode.h"
#include "../../Crypto/Zip/ZipCipher.h"
#include "../../Crypto/WzAES/WzAES.h"
namespace NArchive {
namespace NZip {
struct CCompressingResult
{
Byte Method;
UInt64 UnpackSize;
UInt64 PackSize;
UInt32 CRC;
UInt16 Method;
Byte ExtractVersion;
};
@@ -38,11 +41,16 @@ class CAddCommon
CMyComPtr<ISequentialOutStream> _cryptoStream;
NCrypto::NZip::CEncoder *_filterSpec;
NCrypto::NWzAES::CEncoder *_filterAesSpec;
CMyComPtr<ICompressFilter> _zipCryptoFilter;
CMyComPtr<ICompressFilter> _aesFilter;
public:
CAddCommon(const CCompressionMethodMode &options);
HRESULT Compress(ISequentialInStream *inStream, IOutStream *outStream,
UInt64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult);
ICompressProgressInfo *progress, CCompressingResult &operationResult);
};
}}

View File

@@ -23,7 +23,15 @@ struct CCompressionMethodMode
#endif
bool PasswordIsDefined;
AString Password;
CCompressionMethodMode(): NumMatchFinderCyclesDefined(false) {}
bool IsAesMode;
Byte AesKeyMode;
CCompressionMethodMode():
NumMatchFinderCyclesDefined(false),
PasswordIsDefined(false),
IsAesMode(false),
AesKeyMode(3)
{}
};
}}

View File

@@ -8,6 +8,7 @@
#include "Common/CRC.h"
#include "Common/StringConvert.h"
#include "Common/ComTry.h"
#include "Common/IntToString.h"
#include "Windows/Time.h"
#include "Windows/PropVariant.h"
@@ -61,6 +62,7 @@ DEFINE_GUID(CLSID_CCompressBZip2Decoder,
#endif
#include "../../Crypto/Zip/ZipCipher.h"
#include "../../Crypto/WzAES/WzAES.h"
#ifndef EXCLUDE_COM
#include "../Common/CoderLoader.h"
@@ -147,8 +149,10 @@ const wchar_t *kMethods[] =
};
const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
const wchar_t *kUnknownMethod = L"Unknown";
// const wchar_t *kUnknownMethod = L"Unknown";
const wchar_t *kPPMdMethod = L"PPMd";
const wchar_t *kAESMethod = L"AES";
const wchar_t *kZipCryptoMethod = L"ZipCrypto";
CHandler::CHandler():
m_ArchiveIsOpen(false)
@@ -156,7 +160,7 @@ CHandler::CHandler():
InitMethodProperties();
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
@@ -186,8 +190,8 @@ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
@@ -198,6 +202,17 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
static void MyStrNCpy(char *dest, const char *src, int size)
{
for (int i = 0; i < size; i++)
{
char c = src[i];
dest[i] = c;
if (c == 0)
break;
}
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *aValue)
{
COM_TRY_BEGIN
@@ -244,7 +259,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a
{
AString s;
char *p = s.GetBuffer(size + 1);
strncpy(p, (const char *)(const Byte *)item.Comment, size);
MyStrNCpy(p, (const char *)(const Byte *)item.Comment, size);
p[size] = '\0';
s.ReleaseBuffer();
propVariant = MultiByteToUnicodeString(s, item.GetCodePage());
@@ -252,19 +267,46 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a
break;
}
case kpidCRC:
propVariant = item.FileCRC;
if (item.IsThereCrc())
propVariant = item.FileCRC;
break;
case kpidMethod:
{
UInt16 methodId = item.CompressionMethod;
UString method;
if (item.CompressionMethod < kNumMethods)
method = kMethods[item.CompressionMethod];
else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kWinZipPPMd)
method = kPPMdMethod;
if (item.IsEncrypted())
{
if (methodId == NFileHeader::NCompressionMethod::kWzAES)
{
method = kAESMethod;
CWzAesExtraField aesField;
if (item.CentralExtra.GetWzAesField(aesField))
{
method += L"-";
wchar_t s[32];
ConvertUInt64ToString((aesField.Strength + 1) * 64 , s);
method += s;
method += L" ";
methodId = aesField.Method;
}
}
else
{
method += kZipCryptoMethod;
method += L" ";
}
}
if (methodId < kNumMethods)
method += kMethods[methodId];
else if (methodId == NFileHeader::NCompressionMethod::kWzPPMd)
method += kPPMdMethod;
else
method = kUnknownMethod;
{
wchar_t s[32];
ConvertUInt64ToString(methodId, s);
method += s;
}
propVariant = method;
// propVariant = item.CompressionMethod;
break;
}
case kpidHostOS:
@@ -334,17 +376,303 @@ STDMETHODIMP CHandler::Close()
struct CMethodItem
{
Byte ZipMethod;
UInt16 ZipMethod;
CMyComPtr<ICompressCoder> Coder;
};
class CZipDecoder
{
NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec;
NCrypto::NWzAES::CDecoder *_aesDecoderSpec;
CMyComPtr<ICompressFilter> _zipCryptoDecoder;
CMyComPtr<ICompressFilter> _aesDecoder;
CFilterCoder *filterStreamSpec;
CMyComPtr<ISequentialInStream> filterStream;
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
#ifndef EXCLUDE_COM
CCoderLibraries libraries;
#endif
CObjectVector<CMethodItem> methodItems;
public:
CZipDecoder(): _zipCryptoDecoderSpec(0), _aesDecoderSpec(0), filterStreamSpec(0) {}
static void Init()
{
#ifndef EXCLUDE_COM
N7z::LoadMethodMap();
#endif
}
HRESULT Decode(CInArchive &archive, const CItemEx &item,
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
UInt32 numThreads, Int32 &res);
};
HRESULT CZipDecoder::Decode(CInArchive &archive, const CItemEx &item,
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
UInt32 numThreads, Int32 &res)
{
res = NArchive::NExtract::NOperationResult::kDataError;
CInStreamReleaser inStreamReleaser;
bool needCRC = true;
bool aesMode = false;
UInt16 methodId = item.CompressionMethod;
if (item.IsEncrypted())
if (methodId == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtraField aesField;
if (item.CentralExtra.GetWzAesField(aesField))
{
aesMode = true;
needCRC = aesField.NeedCrc();
}
}
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init(needCRC);
UInt64 authenticationPos;
CMyComPtr<ISequentialInStream> inStream;
{
UInt64 packSize = item.PackSize;
if (aesMode)
{
if (packSize < NCrypto::NWzAES::kMacSize)
return S_OK;
packSize -= NCrypto::NWzAES::kMacSize;
}
UInt64 dataPos = item.GetDataPosition();
inStream.Attach(archive.CreateLimitedStream(dataPos, packSize));
authenticationPos = dataPos + packSize;
}
CMyComPtr<ICompressFilter> cryptoFilter;
if (item.IsEncrypted())
{
if (aesMode)
{
CWzAesExtraField aesField;
if (!item.CentralExtra.GetWzAesField(aesField))
return S_OK;
methodId = aesField.Method;
if (!_aesDecoder)
{
_aesDecoderSpec = new NCrypto::NWzAES::CDecoder;
_aesDecoder = _aesDecoderSpec;
}
cryptoFilter = _aesDecoder;
Byte properties = aesField.Strength;
RINOK(_aesDecoderSpec->SetDecoderProperties2(&properties, 1));
}
else
{
if (!_zipCryptoDecoder)
{
_zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder;
_zipCryptoDecoder = _zipCryptoDecoderSpec;
}
cryptoFilter = _zipCryptoDecoder;
}
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
if (!getTextPassword)
extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
if (getTextPassword)
{
CMyComBSTR password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
AString charPassword;
if (aesMode)
{
charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP);
/*
for (int i = 0;; i++)
{
wchar_t c = password[i];
if (c == 0)
break;
if (c >= 0x80)
{
res = NArchive::NExtract::NOperationResult::kDataError;
return S_OK;
}
charPassword += (char)c;
}
*/
}
else
{
// we use OEM. WinZip/Windows probably use ANSI for some files
charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
}
HRESULT res = cryptoSetPassword->CryptoSetPassword(
(const Byte *)(const char *)charPassword, charPassword.Length());
if (res != S_OK)
return S_OK;
}
else
{
RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
}
}
int m;
for (m = 0; m < methodItems.Size(); m++)
if (methodItems[m].ZipMethod == methodId)
break;
if (m == methodItems.Size())
{
CMethodItem mi;
mi.ZipMethod = methodId;
if (methodId == NFileHeader::NCompressionMethod::kStored)
mi.Coder = new NCompress::CCopyCoder;
else if (methodId == NFileHeader::NCompressionMethod::kShrunk)
mi.Coder = new NCompress::NShrink::CDecoder;
else if (methodId == NFileHeader::NCompressionMethod::kImploded)
mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
else
{
#ifdef EXCLUDE_COM
switch(methodId)
{
case NFileHeader::NCompressionMethod::kDeflated:
mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder;
break;
case NFileHeader::NCompressionMethod::kDeflated64:
mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder64;
break;
case NFileHeader::NCompressionMethod::kBZip2:
mi.Coder = new NCompress::NBZip2::CDecoder;
break;
default:
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
return S_OK;
}
#else
N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 };
if (methodId > 0xFF)
{
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
return S_OK;
}
methodID.ID[2] = (Byte)methodId;
if (methodId == NFileHeader::NCompressionMethod::kStored)
{
methodID.ID[0] = 0;
methodID.IDSize = 1;
}
else if (methodId == NFileHeader::NCompressionMethod::kBZip2)
{
methodID.ID[1] = 0x02;
methodID.ID[2] = 0x02;
}
N7z::CMethodInfo methodInfo;
if (!N7z::GetMethodInfo(methodID, methodInfo))
{
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
return S_OK;
}
RINOK(libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &mi.Coder));
#endif
}
m = methodItems.Add(mi);
}
ICompressCoder *coder = methodItems[m].Coder;
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
Byte properties = (Byte)item.Flags;
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
}
}
#ifdef COMPRESS_MT
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
}
}
#endif
{
HRESULT result;
CMyComPtr<ISequentialInStream> inStreamNew;
if (item.IsEncrypted())
{
if (!filterStream)
{
filterStreamSpec = new CFilterCoder;
filterStream = filterStreamSpec;
}
filterStreamSpec->Filter = cryptoFilter;
if (aesMode)
{
RINOK(_aesDecoderSpec->ReadHeader(inStream));
}
else
{
RINOK(_zipCryptoDecoderSpec->ReadHeader(inStream));
}
RINOK(filterStreamSpec->SetInStream(inStream));
inStreamReleaser.FilterCoder = filterStreamSpec;
inStreamNew = filterStream;
if (aesMode)
{
if (!_aesDecoderSpec->CheckPasswordVerifyCode())
return S_OK;
}
}
else
inStreamNew = inStream;
result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress);
if (result == S_FALSE)
return S_OK;
RINOK(result);
}
bool crcOK = true;
bool authOk = true;
if (needCRC)
crcOK = (outStreamSpec->GetCRC() == item.FileCRC);
if (aesMode)
{
inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAES::kMacSize));
if (_aesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
authOk = false;
}
res = ((crcOK && authOk) ?
NArchive::NExtract::NOperationResult::kOK :
NArchive::NExtract::NOperationResult::kCRCError);
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
CZipDecoder myDecoder;
bool testMode = (_aTestMode != 0);
CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
UInt64 totalUnPacked = 0, totalPacked = 0;
bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode)
@@ -363,37 +691,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
UInt64 currentItemUnPacked, currentItemPacked;
#ifndef EXCLUDE_COM
N7z::LoadMethodMap();
CCoderLibraries libraries;
#endif
CObjectVector<CMethodItem> methodItems;
/*
CCoderLibraries _libraries;
#ifndef COMPRESS_IMPLODE
CCoderLibrary implodeLib;
#endif
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
CMyComPtr<ICompressCoder> implodeDecoder;
CMyComPtr<ICompressCoder> deflateDecoder;
CMyComPtr<ICompressCoder> deflate64Decoder;
CMyComPtr<ICompressCoder> bzip2Decoder;
CZipDecoder::Init();
#ifndef CRYPTO_ZIP
CCoderLibrary cryptoLib;
#endif
*/
NCrypto::NZip::CDecoder *cryptoDecoderSpec;
CMyComPtr<ICompressFilter> cryptoDecoder;
CFilterCoder *filterStreamSpec;
CMyComPtr<ISequentialInStream> filterStream;
// UInt16 mixerCoderMethod;
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked)
{
currentItemUnPacked = 0;
@@ -401,222 +706,58 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
Int32 askMode = testMode ?
NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
const CItemEx &item = m_Items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if(item.IsDirectory() || item.IgnoreItem())
CItemEx item = m_Items[index];
if (!item.FromLocal)
{
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item);
if (res == S_FALSE)
{
if (item.IsDirectory() || realOutStream || testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
}
continue;
}
RINOK(res);
}
if (item.IsDirectory() || item.IgnoreItem())
{
// if (!testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
continue;
}
currentItemUnPacked = item.UnPackSize;
currentItemPacked = item.PackSize;
if (!testMode && (!realOutStream))
continue;
RINOK(extractCallback->PrepareOperation(askMode));
currentItemUnPacked = item.UnPackSize;
currentItemPacked = item.PackSize;
CInStreamReleaser inStreamReleaser;
{
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream);
realOutStream.Release();
CMyComPtr<ISequentialInStream> inStream;
inStream.Attach(m_Archive.CreateLimitedStream(item.GetDataPosition(),
item.PackSize));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalPacked,
&currentTotalUnPacked);
if (item.IsEncrypted())
{
if (!cryptoDecoder)
{
cryptoDecoderSpec = new NCrypto::NZip::CDecoder;
cryptoDecoder = cryptoDecoderSpec;
}
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
RINOK(cryptoDecoder.QueryInterface(
IID_ICryptoSetPassword, &cryptoSetPassword));
if (!getTextPassword)
extractCallback.QueryInterface(
IID_ICryptoGetTextPassword, &getTextPassword);
if (getTextPassword)
{
CMyComBSTR password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
AString anOemPassword = UnicodeStringToMultiByte(
(const wchar_t *)password, CP_OEMCP);
RINOK(cryptoSetPassword->CryptoSetPassword(
(const Byte *)(const char *)anOemPassword, anOemPassword.Length()));
}
else
{
RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
}
}
int m;
for (m = 0; m < methodItems.Size(); m++)
if (methodItems[m].ZipMethod == item.CompressionMethod)
break;
if (m == methodItems.Size())
{
CMethodItem mi;
mi.ZipMethod = (Byte)item.CompressionMethod;
if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored)
mi.Coder = new NCompress::CCopyCoder;
else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kShrunk)
mi.Coder = new NCompress::NShrink::CDecoder;
else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kImploded)
mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
else
{
#ifdef EXCLUDE_COM
switch(item.CompressionMethod)
{
case NFileHeader::NCompressionMethod::kDeflated:
mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder;
break;
case NFileHeader::NCompressionMethod::kDeflated64:
mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder64;
break;
case NFileHeader::NCompressionMethod::kBZip2:
mi.Coder = new NCompress::NBZip2::CDecoder;
break;
default:
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
#else
N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 };
methodID.ID[2] = mi.ZipMethod;
if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored)
{
methodID.ID[0] = 0;
methodID.IDSize = 1;
}
else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kBZip2)
{
methodID.ID[1] = 0x02;
methodID.ID[2] = 0x02;
}
N7z::CMethodInfo methodInfo;
if (!N7z::GetMethodInfo(methodID, methodInfo))
{
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
RINOK(libraries.CreateCoder(methodInfo.FilePath,
methodInfo.Decoder, &mi.Coder));
#endif
}
m = methodItems.Add(mi);
}
ICompressCoder *coder = methodItems[m].Coder;
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
Byte properties = (Byte)item.Flags;
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
}
}
#ifdef COMPRESS_MT
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
}
}
#endif
// case NFileHeader::NCompressionMethod::kImploded:
// switch(item.CompressionMethod)
try
{
HRESULT result;
CMyComPtr<ISequentialInStream> inStreamNew;
if (item.IsEncrypted())
{
if (!filterStream)
{
filterStreamSpec = new CFilterCoder;
filterStream = filterStreamSpec;
filterStreamSpec->Filter = cryptoDecoder;
}
RINOK(cryptoDecoderSpec->ReadHeader(inStream));
RINOK(filterStreamSpec->SetInStream(inStream));
inStreamReleaser.FilterCoder = filterStreamSpec;
/*
switch(item.CompressionMethod)
{
case NFileHeader::NCompressionMethod::kStored:
mixerCoderSpec->SetCoderInfo(0, &currentItemPacked,
&currentItemUnPacked);
mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
break;
default:
mixerCoderSpec->SetCoderInfo(0, &currentItemPacked, NULL);
mixerCoderSpec->SetCoderInfo(1, NULL, &currentItemUnPacked);
break;
}
*/
inStreamNew = filterStream;
}
else
{
inStreamNew = inStream;
}
result = coder->Code(inStreamNew, outStream,
NULL, &currentItemUnPacked, compressProgress);
if (result == S_FALSE)
throw "data error";
if (result != S_OK)
return result;
}
catch(...)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kDataError));
continue;
}
bool crcOK = outStreamSpec->GetCRC() == item.FileCRC;
outStream.Release();
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK :
NArchive::NExtract::NOperationResult::kCRCError))
}
localProgressSpec->Init(extractCallback, false);
localCompressProgressSpec->Init(progress, &currentTotalPacked, &currentTotalUnPacked);
Int32 res;
RINOK(myDecoder.Decode(m_Archive, item, realOutStream, extractCallback,
compressProgress, _numThreads, res));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(res))
}
return S_OK;
COM_TRY_END

View File

@@ -71,6 +71,9 @@ private:
UInt32 m_NumMatchFinderCycles;
bool m_NumMatchFinderCyclesDefined;
bool m_IsAesMode;
Byte m_AesKeyMode;
#ifdef COMPRESS_MT
UInt32 _numThreads;
#endif
@@ -84,6 +87,8 @@ private:
m_NumFastBytes =
m_NumMatchFinderCycles = 0xFFFFFFFF;
m_NumMatchFinderCyclesDefined = false;
m_IsAesMode = false;
m_AesKeyMode = 3; // aes-256
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
#endif

View File

@@ -15,6 +15,7 @@
#include "../../IPassword.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
#include "../../Crypto/WzAES/WzAES.h"
using namespace NWindows;
using namespace NCOM;
@@ -45,6 +46,17 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
return S_OK;
}
static bool IsAsciiString(const UString &s)
{
for (int i = 0; i < s.Length(); i++)
{
wchar_t c = s[i];
if (c < 0x20 || c > 0x7F)
return false;
}
return true;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
@@ -138,6 +150,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (needSlash)
name += kSlash;
updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP);
if (updateItem.Name.Length() > 0xFFFF)
return E_INVALIDARG;
updateItem.IndexInClient = i;
/*
@@ -183,10 +197,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
CMyComBSTR password;
Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password));
if (options.PasswordIsDefined = IntToBool(passwordIsDefined))
RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password));
options.PasswordIsDefined = IntToBool(passwordIsDefined);
if (options.PasswordIsDefined)
{
if (!IsAsciiString((const wchar_t *)password))
return E_INVALIDARG;
if (m_IsAesMode)
{
if (options.Password.Length() > NCrypto::NWzAES::kPasswordSizeMax)
return E_INVALIDARG;
}
options.Password = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
options.IsAesMode = m_IsAesMode;
options.AesKeyMode = m_AesKeyMode;
}
}
else
options.PasswordIsDefined = false;
@@ -197,9 +222,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
Byte mainMethod;
if (m_MainMethod < 0)
mainMethod = ((level == 0) ?
mainMethod = (Byte)(((level == 0) ?
NFileHeader::NCompressionMethod::kStored :
NFileHeader::NCompressionMethod::kDeflated);
NFileHeader::NCompressionMethod::kDeflated));
else
mainMethod = (Byte)m_MainMethod;
options.MethodSequence.Add(mainMethod);
@@ -301,6 +326,33 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
else
return E_INVALIDARG;
}
else if (name.Left(2) == L"EM")
{
if (prop.vt == VT_BSTR)
{
UString valueString = prop.bstrVal;
valueString.MakeUpper();
if (valueString.Left(3) == L"AES")
{
valueString = valueString.Mid(3);
if (valueString == L"128")
m_AesKeyMode = 1;
else if (valueString == L"192")
m_AesKeyMode = 2;
else if (valueString == L"256" || valueString.IsEmpty())
m_AesKeyMode = 3;
else
return E_INVALIDARG;
m_IsAesMode = true;
}
else if (valueString == L"ZIPCRYPTO")
m_IsAesMode = false;
else
return E_INVALIDARG;
}
else
return E_INVALIDARG;
}
else if (name[0] == L'D')
{
UInt32 dicSize = kBZip2DicSizeX5;

View File

@@ -20,8 +20,9 @@ namespace NSignature
static const UInt32 kMarkerSize = 4;
}
const UInt32 kZip64EndOfCentralDirRecordSize = 44;
const UInt32 kEcdSize = 22;
const UInt32 kZip64EcdSize = 44;
const UInt32 kZip64EcdLocatorSize = 20;
/*
struct CEndOfCentralDirectoryRecord
{
@@ -68,7 +69,8 @@ namespace NFileHeader
kPKImploding = 10,
kBZip2 = 12,
kWinZipPPMd = 0x62
kWzPPMd = 0x62,
kWzAES = 0x63
};
const int kNumCompressionMethods = 11;
const Byte kMadeByProgramVersion = 20;
@@ -79,6 +81,15 @@ namespace NFileHeader
const Byte kSupportedVersion = 20;
}
namespace NExtraID
{
enum
{
kZip64 = 0x01,
kWzAES = 0x9901
};
}
const UInt32 kLocalBlockSize = 26;
/*
struct CLocalBlock

View File

@@ -28,6 +28,11 @@ void CInArchive::Close()
m_Stream.Release();
}
HRESULT CInArchive::Seek(UInt64 offset)
{
return m_Stream->Seek(offset, STREAM_SEEK_SET, NULL);
}
//////////////////////////////////////
// Markers
@@ -41,9 +46,8 @@ static inline bool TestMarkerCandidate(const Byte *p, UInt32 &value)
bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
{
m_ArchiveInfo.Clear();
m_ArchiveInfo.StartPosition = 0;
m_Position = m_StreamStartPosition;
if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
if(Seek(m_StreamStartPosition) != S_OK)
return false;
Byte marker[NSignature::kMarkerSize];
@@ -61,24 +65,26 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
UInt32 numBytesPrev = NSignature::kMarkerSize - 1;
memmove(buffer, marker + 1, numBytesPrev);
UInt64 curTestPos = m_StreamStartPosition + 1;
while(true)
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
return false;
break;
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
if (numBytesInBuffer < NSignature::kMarkerSize)
return false;
break;
UInt32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1;
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
{
if (TestMarkerCandidate(buffer + pos, m_Signature))
{
m_ArchiveInfo.StartPosition = curTestPos;
// m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
// m_ArchiveInfo.Base = 0;
m_Position = curTestPos + NSignature::kMarkerSize;
if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK)
if(Seek(m_Position) != S_OK)
return false;
return true;
}
@@ -86,6 +92,7 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
numBytesPrev = numBytesInBuffer - numTests;
memmove(buffer, buffer + numTests, numBytesPrev);
}
return false;
}
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
@@ -184,10 +191,12 @@ void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
archiveInfo = m_ArchiveInfo;
}
/*
void CInArchive::ThrowIncorrectArchiveException()
{
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
}
*/
static UInt32 GetUInt32(const Byte *data)
{
@@ -198,6 +207,21 @@ static UInt32 GetUInt32(const Byte *data)
(((UInt32)(Byte)data[3]) << 24);
}
/*
static UInt16 GetUInt16(const Byte *data)
{
return
((UInt16)(Byte)data[0]) |
(((UInt16)(Byte)data[1]) << 8);
}
*/
static UInt64 GetUInt64(const Byte *data)
{
return GetUInt32(data) | ((UInt64)GetUInt32(data + 4) << 32);
}
void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber)
@@ -212,7 +236,7 @@ void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
remain -= 4;
if (dataSize > remain) // it's bug
dataSize = remain;
if (subBlock.ID == 0x1)
if (subBlock.ID == NFileHeader::NExtraID::kZip64)
{
if (unpackSize == 0xFFFFFFFF)
{
@@ -259,108 +283,298 @@ void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
IncreaseRealPosition(remain);
}
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
HRESULT CInArchive::ReadLocalItem(CItemEx &item)
{
// m_Signature must be kLocalFileHeaderSignature or
// kEndOfCentralDirSignature
// m_Position points to next byte after signature
items.Clear();
if (progress != 0)
item.ExtractVersion.Version = ReadByte();
item.ExtractVersion.HostOS = ReadByte();
item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask;
item.CompressionMethod = ReadUInt16();
item.Time = ReadUInt32();
item.FileCRC = ReadUInt32();
item.PackSize = ReadUInt32();
item.UnPackSize = ReadUInt32();
UInt32 fileNameSize = ReadUInt16();
item.LocalExtraSize = ReadUInt16();
item.Name = ReadFileName(fileNameSize);
item.FileHeaderWithNameSize = 4 + NFileHeader::kLocalBlockSize + fileNameSize;
if (item.LocalExtraSize > 0)
{
UInt64 numItems = items.Size();
RINOK(progress->SetCompleted(&numItems));
UInt64 localHeaderOffset = 0;
UInt32 diskStartNumber = 0;
ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize,
localHeaderOffset, diskStartNumber);
}
/*
if (item.IsDirectory())
item.UnPackSize = 0; // check It
*/
return S_OK;
}
HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item)
{
if (item.FromLocal)
return S_OK;
try
{
RINOK(Seek(m_ArchiveInfo.Base + item.LocalHeaderPosition));
CItemEx localItem;
if (ReadUInt32() != NSignature::kLocalFileHeader)
return S_FALSE;
RINOK(ReadLocalItem(localItem));
if (item.Flags != localItem.Flags)
{
if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated ||
(item.Flags & 0xFFFC) != (localItem.Flags & 0xFFFC))
return S_FALSE;
}
if (item.CompressionMethod != localItem.CompressionMethod ||
// item.Time != localItem.Time ||
(!localItem.HasDescriptor() &&
(
item.FileCRC != localItem.FileCRC ||
item.PackSize != localItem.PackSize ||
item.UnPackSize != localItem.UnPackSize
)
) ||
item.Name.Length() != localItem.Name.Length()
)
return S_FALSE;
item.FileHeaderWithNameSize = localItem.FileHeaderWithNameSize;
item.LocalExtraSize = localItem.LocalExtraSize;
item.LocalExtra = localItem.LocalExtra;
item.FromLocal = true;
}
catch(...) { return S_FALSE; }
return S_OK;
}
HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item)
{
if (item.HasDescriptor())
{
const int kBufferSize = (1 << 12);
Byte buffer[kBufferSize];
UInt32 numBytesInBuffer = 0;
UInt32 packedSize = 0;
bool descriptorWasFound = false;
for (;;)
{
UInt32 processedSize;
RINOK(ReadBytes(buffer + numBytesInBuffer, kBufferSize - numBytesInBuffer, &processedSize));
numBytesInBuffer += processedSize;
if (numBytesInBuffer < NFileHeader::kDataDescriptorSize)
return S_FALSE;
UInt32 i;
for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++)
{
// descriptorSignature field is Info-ZIP's extension
// to Zip specification.
UInt32 descriptorSignature = GetUInt32(buffer + i);
// !!!! It must be fixed for Zip64 archives
UInt32 descriptorPackSize = GetUInt32(buffer + i + 8);
if (descriptorSignature== NSignature::kDataDescriptor && descriptorPackSize == packedSize + i)
{
descriptorWasFound = true;
item.FileCRC = GetUInt32(buffer + i + 4);
item.PackSize = descriptorPackSize;
item.UnPackSize = GetUInt32(buffer + i + 12);
IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - NFileHeader::kDataDescriptorSize))));
break;
}
}
if (descriptorWasFound)
break;
packedSize += i;
int j;
for (j = 0; i < numBytesInBuffer; i++, j++)
buffer[j] = buffer[i];
numBytesInBuffer = j;
}
}
else
IncreaseRealPosition(item.PackSize);
return S_OK;
}
HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
{
if (item.FromLocal)
return S_OK;
try
{
RINOK(ReadLocalItemAfterCdItem(item));
if (item.HasDescriptor())
{
RINOK(Seek(m_ArchiveInfo.Base + item.GetDataPosition() + item.PackSize));
if (ReadUInt32() != NSignature::kDataDescriptor)
return S_FALSE;
UInt32 crc = ReadUInt32();
UInt32 packSize = ReadUInt32();
UInt32 unpackSize = ReadUInt32();
if (crc != item.FileCRC || item.PackSize != packSize || item.UnPackSize != unpackSize)
return S_FALSE;
}
}
catch(...) { return S_FALSE; }
return S_OK;
}
HRESULT CInArchive::ReadCdItem(CItemEx &item)
{
item.FromCentral = true;
item.MadeByVersion.Version = ReadByte();
item.MadeByVersion.HostOS = ReadByte();
item.ExtractVersion.Version = ReadByte();
item.ExtractVersion.HostOS = ReadByte();
item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask;
item.CompressionMethod = ReadUInt16();
item.Time = ReadUInt32();
item.FileCRC = ReadUInt32();
item.PackSize = ReadUInt32();
item.UnPackSize = ReadUInt32();
UInt16 headerNameSize = ReadUInt16();
UInt16 headerExtraSize = ReadUInt16();
UInt16 headerCommentSize = ReadUInt16();
UInt32 headerDiskNumberStart = ReadUInt16();
item.InternalAttributes = ReadUInt16();
item.ExternalAttributes = ReadUInt32();
item.LocalHeaderPosition = ReadUInt32();
item.Name = ReadFileName(headerNameSize);
if (headerExtraSize > 0)
{
ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize,
item.LocalHeaderPosition, headerDiskNumberStart);
}
while(m_Signature == NSignature::kLocalFileHeader)
if (headerDiskNumberStart != 0)
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
// May be these strings must be deleted
/*
if (item.IsDirectory())
item.UnPackSize = 0;
*/
ReadBuffer(item.Comment, headerCommentSize);
return S_OK;
}
HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
{
RINOK(Seek(offset));
const UInt32 kEcd64Size = 56;
Byte buf[kEcd64Size];
if(!ReadBytesAndTestSize(buf, kEcd64Size))
return S_FALSE;
if (GetUInt32(buf) != NSignature::kZip64EndOfCentralDir)
return S_FALSE;
// cdInfo.NumEntries = GetUInt64(buf + 24);
cdInfo.Size = GetUInt64(buf + 40);
cdInfo.Offset = GetUInt64(buf + 48);
return S_OK;
}
HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
{
UInt64 endPosition;
RINOK(m_Stream->Seek(0, STREAM_SEEK_END, &endPosition));
const UInt32 kBufSizeMax = (1 << 16) + kEcdSize + kZip64EcdLocatorSize;
Byte buf[kBufSizeMax];
UInt32 bufSize = (endPosition < kBufSizeMax) ? (UInt32)endPosition : kBufSizeMax;
if (bufSize < kEcdSize)
return S_FALSE;
UInt64 startPosition = endPosition - bufSize;
RINOK(m_Stream->Seek(startPosition, STREAM_SEEK_SET, &m_Position));
if (m_Position != startPosition)
return S_FALSE;
if (!ReadBytesAndTestSize(buf, bufSize))
return S_FALSE;
for (int i = (int)(bufSize - kEcdSize); i >= 0; i--)
{
if (GetUInt32(buf + i) == NSignature::kEndOfCentralDir)
{
if (i >= kZip64EcdLocatorSize)
{
const Byte *locator = buf + i - kZip64EcdLocatorSize;
if (GetUInt32(locator) == NSignature::kZip64EndOfCentralDirLocator)
{
UInt64 ecd64Offset = GetUInt64(locator + 8);
if (TryEcd64(ecd64Offset, cdInfo) == S_OK)
return S_OK;
if (TryEcd64(m_ArchiveInfo.StartPosition + ecd64Offset, cdInfo) == S_OK)
{
m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
return S_OK;
}
}
}
if (GetUInt32(buf + i + 4) == 0)
{
// cdInfo.NumEntries = GetUInt16(buf + i + 10);
cdInfo.Size = GetUInt32(buf + i + 12);
cdInfo.Offset = GetUInt32(buf + i + 16);
return S_OK;
}
}
}
return S_FALSE;
}
HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize)
{
items.Clear();
RINOK(m_Stream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position));
if (m_Position != cdOffset)
return S_FALSE;
while(m_Position - cdOffset < cdSize)
{
if(ReadUInt32() != NSignature::kCentralFileHeader)
return S_FALSE;
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
items.Add(cdItem);
}
return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE;
}
HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize)
{
m_ArchiveInfo.Base = 0;
CCdInfo cdInfo;
RINOK(FindCd(cdInfo));
HRESULT res = S_FALSE;
cdSize = cdInfo.Size;
cdOffset = cdInfo.Offset;
res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize);
if (res == S_FALSE && m_ArchiveInfo.Base == 0)
{
res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize);
if (res == S_OK)
m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
}
if (!ReadUInt32(m_Signature))
return S_FALSE;
return res;
}
HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset)
{
items.Clear();
while (m_Signature == NSignature::kLocalFileHeader)
{
// FSeek points to next byte after signature
// NFileHeader::CLocalBlock localHeader;
CItemEx item;
item.LocalHeaderPosition = m_Position - m_StreamStartPosition - 4; // points to signature;
// SafeReadBytes(&localHeader, sizeof(localHeader));
item.ExtractVersion.Version = ReadByte();
item.ExtractVersion.HostOS = ReadByte();
item.Flags = ReadUInt16() & NFileHeader::NFlags::kUsedBitsMask;
item.CompressionMethod = ReadUInt16();
item.Time = ReadUInt32();
item.FileCRC = ReadUInt32();
item.PackSize = ReadUInt32();
item.UnPackSize = ReadUInt32();
UInt32 fileNameSize = ReadUInt16();
item.LocalExtraSize = ReadUInt16();
item.Name = ReadFileName(fileNameSize);
/*
if (!NItemName::IsNameLegal(item.Name))
ThrowIncorrectArchiveException();
*/
item.FileHeaderWithNameSize = 4 +
NFileHeader::kLocalBlockSize + fileNameSize;
// IncreaseRealPosition(item.LocalExtraSize);
if (item.LocalExtraSize > 0)
{
UInt64 localHeaderOffset = 0;
UInt32 diskStartNumber = 0;
CExtraBlock extraBlock;
ReadExtra(item.LocalExtraSize, extraBlock, item.UnPackSize, item.PackSize,
localHeaderOffset, diskStartNumber);
}
if (item.HasDescriptor())
{
const int kBufferSize = (1 << 12);
Byte buffer[kBufferSize];
UInt32 numBytesInBuffer = 0;
UInt32 packedSize = 0;
bool descriptorWasFound = false;
while (true)
{
UInt32 processedSize;
RINOK(ReadBytes(buffer + numBytesInBuffer,
kBufferSize - numBytesInBuffer, &processedSize));
numBytesInBuffer += processedSize;
if (numBytesInBuffer < NFileHeader::kDataDescriptorSize)
ThrowIncorrectArchiveException();
UInt32 i;
for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++)
{
// descriptorSignature field is Info-ZIP's extension
// to Zip specification.
UInt32 descriptorSignature = GetUInt32(buffer + i);
// !!!! It must be fixed for Zip64 archives
UInt32 descriptorPackSize = GetUInt32(buffer + i + 8);
if (descriptorSignature== NSignature::kDataDescriptor &&
descriptorPackSize == packedSize + i)
{
descriptorWasFound = true;
item.FileCRC = GetUInt32(buffer + i + 4);
item.PackSize = descriptorPackSize;
item.UnPackSize = GetUInt32(buffer + i + 12);
IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i -
NFileHeader::kDataDescriptorSize))));
break;
};
}
if (descriptorWasFound)
break;
packedSize += i;
int j;
for (j = 0; i < numBytesInBuffer; i++, j++)
buffer[j] = buffer[i];
numBytesInBuffer = j;
}
}
else
IncreaseRealPosition(item.PackSize);
RINOK(ReadLocalItem(item));
item.FromLocal = true;
ReadLocalItemDescriptor(item);
items.Add(item);
if (progress != 0)
{
@@ -370,8 +584,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
if (!ReadUInt32(m_Signature))
break;
}
UInt64 centralDirectorySize = 0;
UInt64 centralDirectoryStartOffset = m_Position - 4;
cdOffset = m_Position - 4;
for(int i = 0; i < items.Size(); i++)
{
if (progress != 0)
@@ -379,152 +592,143 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
UInt64 numItems = items.Size();
RINOK(progress->SetCompleted(&numItems));
}
// if(m_Signature == NSignature::kEndOfCentralDir)
// break;
if(m_Signature != NSignature::kCentralFileHeader)
ThrowIncorrectArchiveException();
// NFileHeader::CBlock header;
// SafeReadBytes(&header, sizeof(header));
return S_FALSE;
Byte headerMadeByVersionVersion = ReadByte();
Byte headerMadeByVersionHostOS = ReadByte();
Byte centalHeaderExtractVersionVersion = ReadByte();
Byte centalHeaderExtractVersionHostOS = ReadByte();
UInt16 headerFlags = ReadUInt16() & NFileHeader::NFlags::kUsedBitsMask;
UInt16 headerCompressionMethod = ReadUInt16();
UInt32 headerTime = ReadUInt32();
UInt32 headerFileCRC = ReadUInt32();
UInt64 headerPackSize = ReadUInt32();
UInt64 headerUnPackSize = ReadUInt32();
UInt16 headerNameSize = ReadUInt16();
UInt16 headerExtraSize = ReadUInt16();
UInt16 headerCommentSize = ReadUInt16();
UInt32 headerDiskNumberStart = ReadUInt16();
UInt16 headerInternalAttributes = ReadUInt16();
UInt32 headerExternalAttributes = ReadUInt32();
UInt64 localHeaderOffset = ReadUInt32();
AString centralName = ReadFileName(headerNameSize);
// item.Name = ReadFileName(fileNameSize);
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
CExtraBlock centralExtra;
if (headerExtraSize > 0)
if (i == 0)
{
ReadExtra(headerExtraSize, centralExtra, headerUnPackSize, headerPackSize, localHeaderOffset, headerDiskNumberStart);
if (cdItem.LocalHeaderPosition == 0)
m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
}
int index;
int left = 0, right = items.Size();
while(true)
for (;;)
{
if (left >= right)
ThrowIncorrectArchiveException();
return S_FALSE;
index = (left + right) / 2;
UInt64 position = items[index].LocalHeaderPosition;
if (localHeaderOffset == position)
UInt64 position = items[index].LocalHeaderPosition - m_ArchiveInfo.Base;
if (cdItem.LocalHeaderPosition == position)
break;
if (localHeaderOffset < position)
if (cdItem.LocalHeaderPosition < position)
right = index;
else
left = index + 1;
}
CItemEx &item = items[index];
item.MadeByVersion.Version = headerMadeByVersionVersion;
item.MadeByVersion.HostOS = headerMadeByVersionHostOS;
item.CentralExtra = centralExtra;
item.LocalHeaderPosition = cdItem.LocalHeaderPosition;
item.MadeByVersion = cdItem.MadeByVersion;
item.CentralExtra = cdItem.CentralExtra;
if (
// item.ExtractVersion != centalHeaderExtractVersion ||
item.Flags != headerFlags ||
item.CompressionMethod != headerCompressionMethod ||
// item.Time != header.Time ||
item.FileCRC != headerFileCRC)
ThrowIncorrectArchiveException();
if (item.Name.Length() != centralName.Length())
ThrowIncorrectArchiveException(); // test it maybe better compare names
item.Name = centralName;
// item.CentralExtraPosition = m_Position;
// item.CentralExtraSize = headerExtraSize;
// item.CommentSize = headerCommentSize;
if (headerDiskNumberStart != 0)
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
item.InternalAttributes = headerInternalAttributes;
item.ExternalAttributes = headerExternalAttributes;
// May be these strings must be deleted
if (item.IsDirectory())
{
// if (item.PackSize != 0 /* || item.UnPackSize != 0 */)
// ThrowIncorrectArchiveException();
item.UnPackSize = 0;
}
UInt32 currentRecordSize = 4 + NFileHeader::kCentralBlockSize +
headerNameSize + headerExtraSize + headerCommentSize;
centralDirectorySize += currentRecordSize;
// IncreaseRealPosition(headerExtraSize);
if (
item.PackSize != headerPackSize ||
item.UnPackSize != headerUnPackSize
)
ThrowIncorrectArchiveException();
// IncreaseRealPosition(headerCommentSize);
ReadBuffer(item.Comment, headerCommentSize);
// item.ExtractVersion != cdItem.ExtractVersion ||
item.Flags != cdItem.Flags ||
item.CompressionMethod != cdItem.CompressionMethod ||
// item.Time != cdItem.Time ||
item.FileCRC != cdItem.FileCRC)
return S_FALSE;
if (item.Name.Length() != cdItem.Name.Length() ||
item.PackSize != cdItem.PackSize ||
item.UnPackSize != cdItem.UnPackSize
)
return S_FALSE;
item.Name = cdItem.Name;
item.InternalAttributes = cdItem.InternalAttributes;
item.ExternalAttributes = cdItem.ExternalAttributes;
item.Comment = cdItem.Comment;
item.FromCentral = cdItem.FromCentral;
if (!ReadUInt32(m_Signature))
break;
return S_FALSE;
}
return S_OK;
}
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
// m_Signature must be kLocalFileHeaderSignature or
// kEndOfCentralDirSignature
// m_Position points to next byte after signature
items.Clear();
if (progress != 0)
{
UInt64 numItems = items.Size();
RINOK(progress->SetCompleted(&numItems));
}
UInt64 cdSize, cdStartOffset;
HRESULT res = ReadCd(items, cdStartOffset, cdSize);
if (res != S_FALSE && res != S_OK)
return res;
/*
if (res != S_OK)
return res;
res = S_FALSE;
*/
if (res == S_FALSE)
{
m_ArchiveInfo.Base = 0;
RINOK(m_Stream->Seek(m_ArchiveInfo.StartPosition, STREAM_SEEK_SET, &m_Position));
if (m_Position != m_ArchiveInfo.StartPosition)
return S_FALSE;
if (!ReadUInt32(m_Signature))
return S_FALSE;
RINOK(ReadLocalsAndCd(items, progress, cdStartOffset));
cdSize = (m_Position - 4) - cdStartOffset;
cdStartOffset -= m_ArchiveInfo.Base;
}
UInt32 thisDiskNumber = 0;
UInt32 startCDDiskNumber = 0;
UInt64 numEntriesInCDOnThisDisk = 0;
UInt64 numEntriesInCD = 0;
UInt64 cdSize = 0;
UInt64 cdSizeFromRecord = 0;
UInt64 cdStartOffsetFromRecord = 0;
bool isZip64 = false;
UInt64 zip64EndOfCDStartOffset = m_Position - 4;
UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base;
if(m_Signature == NSignature::kZip64EndOfCentralDir)
{
isZip64 = true;
UInt64 recordSize = ReadUInt64();
UInt16 versionMade = ReadUInt16();
UInt16 versionNeedExtract = ReadUInt16();
/* UInt16 versionMade = */ ReadUInt16();
/* UInt16 versionNeedExtract = */ ReadUInt16();
thisDiskNumber = ReadUInt32();
startCDDiskNumber = ReadUInt32();
numEntriesInCDOnThisDisk = ReadUInt64();
numEntriesInCD = ReadUInt64();
cdSize = ReadUInt64();
cdSizeFromRecord = ReadUInt64();
cdStartOffsetFromRecord = ReadUInt64();
IncreaseRealPosition(recordSize - kZip64EndOfCentralDirRecordSize);
IncreaseRealPosition(recordSize - kZip64EcdSize);
if (!ReadUInt32(m_Signature))
return S_FALSE;
if (thisDiskNumber != 0 || startCDDiskNumber != 0)
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
if (numEntriesInCDOnThisDisk != items.Size() ||
numEntriesInCD != items.Size() ||
cdSize != centralDirectorySize ||
(cdStartOffsetFromRecord != centralDirectoryStartOffset &&
cdSizeFromRecord != cdSize ||
(cdStartOffsetFromRecord != cdStartOffset &&
(!items.IsEmpty())))
ThrowIncorrectArchiveException();
return S_FALSE;
}
if(m_Signature == NSignature::kZip64EndOfCentralDirLocator)
{
UInt32 startEndCDDiskNumber = ReadUInt32();
/* UInt32 startEndCDDiskNumber = */ ReadUInt32();
UInt64 endCDStartOffset = ReadUInt64();
UInt32 numberOfDisks = ReadUInt32();
if (zip64EndOfCDStartOffset != endCDStartOffset)
ThrowIncorrectArchiveException();
/* UInt32 numberOfDisks = */ ReadUInt32();
if (zip64EcdStartOffset != endCDStartOffset)
return S_FALSE;
if (!ReadUInt32(m_Signature))
return S_FALSE;
}
if(m_Signature != NSignature::kEndOfCentralDir)
ThrowIncorrectArchiveException();
return S_FALSE;
UInt16 thisDiskNumber16 = ReadUInt16();
if (!isZip64 || thisDiskNumber16)
@@ -542,9 +746,9 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
if (!isZip64 || numEntriesInCD16 != 0xFFFF)
numEntriesInCD = numEntriesInCD16;
UInt32 cdSize32 = ReadUInt32();
if (!isZip64 || cdSize32 != 0xFFFFFFFF)
cdSize = cdSize32;
UInt32 cdSizeFromRecord32 = ReadUInt32();
if (!isZip64 || cdSizeFromRecord32 != 0xFFFFFFFF)
cdSizeFromRecord = cdSizeFromRecord32;
UInt32 cdStartOffsetFromRecord32 = ReadUInt32();
if (!isZip64 || cdStartOffsetFromRecord32 != 0xFFFFFFFF)
@@ -557,10 +761,10 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
if ((UInt16)numEntriesInCDOnThisDisk != ((UInt16)items.Size()) ||
(UInt16)numEntriesInCD != ((UInt16)items.Size()) ||
(UInt32)cdSize != (UInt32)centralDirectorySize ||
((UInt32)(cdStartOffsetFromRecord) != (UInt32)centralDirectoryStartOffset &&
(UInt32)cdSizeFromRecord != (UInt32)cdSize ||
((UInt32)(cdStartOffsetFromRecord) != (UInt32)cdStartOffset &&
(!items.IsEmpty())))
ThrowIncorrectArchiveException();
return S_FALSE;
return S_OK;
}
@@ -569,8 +773,9 @@ ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 siz
{
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
SeekInArchive(position);
streamSpec->Init(m_Stream, size);
SeekInArchive(m_ArchiveInfo.Base + position);
streamSpec->SetStream(m_Stream);
streamSpec->Init(size);
return inStream.Detach();
}

View File

@@ -33,9 +33,16 @@ public:
class CInArchiveInfo
{
public:
UInt64 Base;
UInt64 StartPosition;
CByteBuffer Comment;
void Clear() { Comment.SetCapacity(0); }
CInArchiveInfo(): Base(0), StartPosition(0) {}
void Clear()
{
Base = 0;
StartPosition = 0;
Comment.SetCapacity(0);
}
};
class CProgressVirt
@@ -44,6 +51,13 @@ public:
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
};
struct CCdInfo
{
// UInt64 NumEntries;
UInt64 Size;
UInt64 Offset;
};
class CInArchive
{
CMyComPtr<IInStream> m_Stream;
@@ -53,6 +67,8 @@ class CInArchive
CInArchiveInfo m_ArchiveInfo;
AString m_NameBuffer;
HRESULT Seek(UInt64 offset);
bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
bool ReadUInt32(UInt32 &signature);
AString ReadFileName(UInt32 nameSize);
@@ -67,16 +83,24 @@ class CInArchive
UInt64 ReadUInt64();
void IncreaseRealPosition(UInt64 addValue);
void ThrowIncorrectArchiveException();
void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber);
HRESULT ReadLocalItem(CItemEx &item);
HRESULT ReadLocalItemDescriptor(CItemEx &item);
HRESULT ReadCdItem(CItemEx &item);
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
HRESULT FindCd(CCdInfo &cdInfo);
HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize);
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize);
HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset);
public:
HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
HRESULT ReadLocalItemAfterCdItem(CItemEx &item);
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
void Close();
void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
void DirectGetBytes(void *data, UInt32 num);
bool SeekInArchive(UInt64 position);
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
IInStream* CreateStream();

View File

@@ -19,31 +19,38 @@ bool operator!=(const CVersion &v1, const CVersion &v2)
return !(v1 == v2);
}
bool CItem::IsEncrypted() const
bool CLocalItem::IsEncrypted() const
{ return (Flags & NFileHeader::NFlags::kEncryptedMask) != 0; }
bool CItem::HasDescriptor() const
bool CLocalItem::HasDescriptor() const
{ return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
bool CItem::IsImplodeBigDictionary() const
bool CLocalItem::IsImplodeBigDictionary() const
{
if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
throw 12312212;
return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0;
}
bool CItem::IsImplodeLiteralsOn() const
bool CLocalItem::IsImplodeLiteralsOn() const
{
if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
throw 12312213;
return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0;
}
static const char *kUnknownAttributes = "Unknown file attributes";
bool CLocalItem::IsDirectory() const
{
return NItemName::HasTailSlash(Name, GetCodePage());
}
bool CItem::IsDirectory() const
{
if (NItemName::HasTailSlash(Name, GetCodePage()))
return true;
if (!FromCentral)
return false;
WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF);
switch(MadeByVersion.HostOS)
{
@@ -83,34 +90,40 @@ bool CItem::IsDirectory() const
}
}
UInt32 CLocalItem::GetWinAttributes() const
{
DWORD winAttributes = 0;
if (IsDirectory())
winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
return winAttributes;
}
UInt32 CItem::GetWinAttributes() const
{
DWORD winAttributes;
DWORD winAttributes = 0;
switch(MadeByVersion.HostOS)
{
case NFileHeader::NHostOS::kFAT:
case NFileHeader::NHostOS::kNTFS:
winAttributes = ExternalAttributes;
if (FromCentral)
winAttributes = ExternalAttributes;
break;
default:
winAttributes = 0; // must be converted from unix value;;
winAttributes = 0; // must be converted from unix value;
}
if (IsDirectory()) // test it;
winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
return winAttributes;
}
void CItem::ClearFlags()
{ Flags = 0; }
void CItem::SetFlagBits(int startBitNumber, int numBits, int value)
void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value)
{
WORD mask = ((1 << numBits) - 1) << startBitNumber;
UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber);
Flags &= ~mask;
Flags |= value << startBitNumber;
}
void CItem::SetBitMask(int bitMask, bool enable)
void CLocalItem::SetBitMask(int bitMask, bool enable)
{
if(enable)
Flags |= bitMask;
@@ -118,7 +131,7 @@ void CItem::SetBitMask(int bitMask, bool enable)
Flags &= ~bitMask;
}
void CItem::SetEncrypted(bool encrypted)
void CLocalItem::SetEncrypted(bool encrypted)
{ SetBitMask(NFileHeader::NFlags::kEncryptedMask, encrypted); }
}}

View File

@@ -27,6 +27,46 @@ struct CExtraSubBlock
CByteBuffer Data;
};
struct CWzAesExtraField
{
UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2,
// UInt16 VendorId; // "AE"
Byte Strength; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit
UInt16 Method;
CWzAesExtraField(): VendorVersion(2), Strength(3), Method(0) {}
bool NeedCrc() const { return (VendorVersion == 1); }
bool ParseFromSubBlock(const CExtraSubBlock &sb)
{
if (sb.ID != NFileHeader::NExtraID::kWzAES)
return false;
if (sb.Data.GetCapacity() < 7)
return false;
const Byte *p = (const Byte *)sb.Data;
VendorVersion = (((UInt16)p[1]) << 8) | p[0];
if (p[2] != 'A' || p[3] != 'E')
return false;
Strength = p[4];
Method = (((UInt16)p[6]) << 16) | p[5];
return true;
}
void SetSubBlock(CExtraSubBlock &sb) const
{
sb.Data.SetCapacity(7);
sb.ID = NFileHeader::NExtraID::kWzAES;
Byte *p = (Byte *)sb.Data;
p[0] = (Byte)VendorVersion;
p[1] = (Byte)(VendorVersion >> 8);
p[2] = 'A';
p[3] = 'E';
p[4] = Strength;
p[5] = (Byte)Method;
p[6] = (Byte)(Method >> 8);
}
};
struct CExtraBlock
{
CObjectVector<CExtraSubBlock> SubBlocks;
@@ -38,13 +78,38 @@ struct CExtraBlock
res += SubBlocks[i].Data.GetCapacity() + 2 + 2;
return res;
}
bool GetWzAesField(CWzAesExtraField &aesField) const
{
// size_t res = 0;
for (int i = 0; i < SubBlocks.Size(); i++)
if (aesField.ParseFromSubBlock(SubBlocks[i]))
return true;
return false;
}
bool HasWzAesField() const
{
CWzAesExtraField aesField;
return GetWzAesField(aesField);
}
void RemoveUnknownSubBlocks()
{
for (int i = SubBlocks.Size() - 1; i >= 0;)
{
const CExtraSubBlock &subBlock = SubBlocks[i];
if (subBlock.ID != NFileHeader::NExtraID::kWzAES)
SubBlocks.Delete(i);
else
i--;
}
}
};
class CItem
class CLocalItem
{
public:
CVersion MadeByVersion;
CVersion ExtractVersion;
UInt16 Flags;
UInt16 CompressionMethod;
@@ -52,16 +117,10 @@ public:
UInt32 FileCRC;
UInt64 PackSize;
UInt64 UnPackSize;
UInt16 InternalAttributes;
UInt32 ExternalAttributes;
AString Name;
UInt64 LocalHeaderPosition;
UInt16 LocalExtraSize;
CExtraBlock CentralExtra;
CByteBuffer Comment;
CExtraBlock LocalExtra;
bool IsEncrypted() const;
@@ -74,19 +133,55 @@ public:
bool HasDescriptor() const;
WORD GetCodePage() const
{
return (MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT
|| MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS
) ? CP_OEMCP : CP_ACP;
}
private:
void SetFlagBits(int startBitNumber, int numBits, int value);
void SetBitMask(int bitMask, bool enable);
public:
void ClearFlags();
void ClearFlags() { Flags = 0; }
void SetEncrypted(bool encrypted);
WORD GetCodePage() const
{
return CP_OEMCP;
}
};
class CItem: public CLocalItem
{
public:
CVersion MadeByVersion;
UInt16 InternalAttributes;
UInt32 ExternalAttributes;
UInt64 LocalHeaderPosition;
CExtraBlock CentralExtra;
CByteBuffer Comment;
bool FromLocal;
bool FromCentral;
bool IsDirectory() const;
UInt32 GetWinAttributes() const;
bool IsThereCrc() const
{
if (CompressionMethod == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtraField aesField;
if (CentralExtra.GetWzAesField(aesField))
return aesField.NeedCrc();
}
return true;
}
WORD GetCodePage() const
{
return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT
|| MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS
) ? CP_OEMCP : CP_ACP);
}
CItem() : FromLocal(false), FromCentral(false) {}
};
}}

View File

@@ -13,6 +13,7 @@ class CItemEx: public CItem
{
public:
UInt32 FileHeaderWithNameSize;
UInt16 LocalExtraSize;
UInt64 GetLocalFullSize() const
{ return FileHeaderWithNameSize + LocalExtraSize + PackSize +

View File

@@ -22,26 +22,28 @@ void COutArchive::MoveBasePosition(UInt64 distanceToMove)
m_BasePosition += distanceToMove; // test overflow
}
void COutArchive::PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64)
void COutArchive::PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption)
{
m_IsZip64 = isZip64;
m_ExtraSize = isZip64 ? (4 + 8 + 8) : 0;
if (aesEncryption)
m_ExtraSize += 4 + 7;
m_LocalFileHeaderSize = 4 + NFileHeader::kLocalBlockSize + fileNameLength + m_ExtraSize;
}
void COutArchive::PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize)
void COutArchive::PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption)
{
// We test it to 0xF8000000 to support case when compressed size
// can be larger than uncompressed size.
PrepareWriteCompressedDataZip64(fileNameLength, unPackSize >= 0xF8000000);
PrepareWriteCompressedDataZip64(fileNameLength, unPackSize >= 0xF8000000, aesEncryption);
}
void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize)
void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption)
{
bool isUnPack64 = unPackSize >= 0xFFFFFFFF;
bool isPack64 = packSize >= 0xFFFFFFFF;
bool isZip64 = isPack64 || isUnPack64;
PrepareWriteCompressedDataZip64(fileNameLength, isZip64);
PrepareWriteCompressedDataZip64(fileNameLength, isZip64, aesEncryption);
}
void COutArchive::WriteBytes(const void *buffer, UInt32 size)
@@ -86,7 +88,21 @@ void COutArchive::WriteUInt64(UInt64 value)
}
}
HRESULT COutArchive::WriteLocalHeader(const CItem &item)
void COutArchive::WriteExtra(const CExtraBlock &extra)
{
if (extra.SubBlocks.Size() != 0)
{
for (int i = 0; i < extra.SubBlocks.Size(); i++)
{
const CExtraSubBlock &subBlock = extra.SubBlocks[i];
WriteUInt16(subBlock.ID);
WriteUInt16((UInt16)subBlock.Data.GetCapacity());
WriteBytes(subBlock.Data, (UInt32)subBlock.Data.GetCapacity());
}
}
}
HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item)
{
m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
@@ -101,29 +117,32 @@ HRESULT COutArchive::WriteLocalHeader(const CItem &item)
WriteUInt32(item.FileCRC);
WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.PackSize);
WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize);
WriteUInt16(item.Name.Length());
UInt16 localExtraSize = isZip64 ? (4 + 16): 0;
if (localExtraSize > m_ExtraSize)
return E_FAIL;
WriteUInt16(m_ExtraSize); // test it;
WriteBytes((const char *)item.Name, item.Name.Length());
if (m_ExtraSize > 0)
WriteUInt16((UInt16)item.Name.Length());
{
UInt16 remain = m_ExtraSize - 4;
WriteUInt16(0x1); // Zip64 Tag;
WriteUInt16(remain);
if (isZip64)
{
WriteUInt64(item.UnPackSize);
WriteUInt64(item.PackSize);
remain -= 16;
}
for (int i = 0; i < remain; i++)
WriteByte(0);
UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 16): 0) + item.LocalExtra.GetSize());
if (localExtraSize > m_ExtraSize)
return E_FAIL;
}
WriteUInt16((UInt16)m_ExtraSize); // test it;
WriteBytes((const char *)item.Name, item.Name.Length());
UInt32 extraPos = 0;
if (isZip64)
{
extraPos += 4 + 16;
WriteUInt16(NFileHeader::NExtraID::kZip64);
WriteUInt16(16);
WriteUInt64(item.UnPackSize);
WriteUInt64(item.PackSize);
}
WriteExtra(item.LocalExtra);
extraPos += (UInt32)item.LocalExtra.GetSize();
for (; extraPos < m_ExtraSize; extraPos++)
WriteByte(0);
MoveBasePosition(item.PackSize);
m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
return S_OK;
return m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
}
void COutArchive::WriteCentralHeader(const CItem &item)
@@ -146,10 +165,10 @@ void COutArchive::WriteCentralHeader(const CItem &item)
WriteUInt32(item.FileCRC);
WriteUInt32(isPack64 ? 0xFFFFFFFF: (UInt32)item.PackSize);
WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize);
WriteUInt16(item.Name.Length());
UInt16 zip64ExtraSize = (isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0);
UInt16 centralExtraSize = isZip64 ? (4 + zip64ExtraSize) : 0;
centralExtraSize += (UInt16)item.CentralExtra.GetSize();
WriteUInt16((UInt16)item.Name.Length());
UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0));
UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0);
centralExtraSize = (UInt16)(centralExtraSize + item.CentralExtra.GetSize());
WriteUInt16(centralExtraSize); // test it;
WriteUInt16((UInt16)item.Comment.GetCapacity());
WriteUInt16(0); // DiskNumberStart;
@@ -159,7 +178,7 @@ void COutArchive::WriteCentralHeader(const CItem &item)
WriteBytes((const char *)item.Name, item.Name.Length());
if (isZip64)
{
WriteUInt16(0x1); // Zip64 Tag;
WriteUInt16(NFileHeader::NExtraID::kZip64);
WriteUInt16(zip64ExtraSize);
if(isUnPack64)
WriteUInt64(item.UnPackSize);
@@ -168,16 +187,7 @@ void COutArchive::WriteCentralHeader(const CItem &item)
if(isPosition64)
WriteUInt64(item.LocalHeaderPosition);
}
if (item.CentralExtra.SubBlocks.Size() != 0)
{
for (int i = 0; i < item.CentralExtra.SubBlocks.Size(); i++)
{
CExtraSubBlock subBlock = item.CentralExtra.SubBlocks[i];
WriteUInt16(subBlock.ID);
WriteUInt16((UInt16)subBlock.Data.GetCapacity());
WriteBytes(subBlock.Data, (UInt32)subBlock.Data.GetCapacity());
}
}
WriteExtra(item.CentralExtra);
if (item.Comment.GetCapacity() > 0)
WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity());
}
@@ -199,7 +209,7 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByte
if (isZip64)
{
WriteUInt32(NSignature::kZip64EndOfCentralDir);
WriteUInt64(kZip64EndOfCentralDirRecordSize); // ThisDiskNumber = 0;
WriteUInt64(kZip64EcdSize); // ThisDiskNumber = 0;
WriteUInt16(45); // version
WriteUInt16(45); // version
WriteUInt32(0); // ThisDiskNumber = 0;
@@ -217,8 +227,8 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByte
WriteUInt32(NSignature::kEndOfCentralDir);
WriteUInt16(0); // ThisDiskNumber = 0;
WriteUInt16(0); // StartCentralDirectoryDiskNumber;
WriteUInt16(items64 ? 0xFFFF: (UInt16)items.Size());
WriteUInt16(items64 ? 0xFFFF: (UInt16)items.Size());
WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size()));
WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size()));
WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize);
WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset);
UInt16 commentSize = (UInt16)comment.GetCapacity();

View File

@@ -29,14 +29,15 @@ class COutArchive
void WriteExtraHeader(const CItem &item);
void WriteCentralHeader(const CItem &item);
void WriteExtra(const CExtraBlock &extra);
public:
void Create(IOutStream *outStream);
void MoveBasePosition(UInt64 distanceToMove);
UInt64 GetCurrentPosition() const { return m_BasePosition; };
void PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64);
void PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize);
void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize);
HRESULT WriteLocalHeader(const CItem &item);
void PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption);
void PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption);
void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption);
HRESULT WriteLocalHeader(const CLocalItem &item);
void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment);

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
#include <stdio.h>
#include "ZipUpdate.h"
#include "ZipAddCommon.h"
#include "ZipOut.h"
@@ -10,180 +12,246 @@
#include "Common/AutoPtr.h"
#include "Common/StringConvert.h"
#include "Windows/Defs.h"
#include "Windows/Thread.h"
#include "../../Common/ProgressUtils.h"
#ifdef COMPRESS_MT
#include "../../Common/ProgressMt.h"
#endif
#include "../../Common/LimitedStreams.h"
#include "../../Common/OutMemStream.h"
#include "../../Compress/Copy/CopyCoder.h"
#include "../Common/InStreamWithCRC.h"
using namespace NWindows;
using namespace NSynchronization;
namespace NArchive {
namespace NZip {
class CCriticalSectionLock2
{
CCriticalSection *_object;
void Unlock() { if (_object != 0) _object->Leave(); }
public:
CCriticalSectionLock2(): _object(0) {}
void Set(CCriticalSection &object) { _object = &object; _object->Enter(); }
~CCriticalSectionLock2() { Unlock(); }
};
static const Byte kMadeByHostOS = NFileHeader::NHostOS::kFAT;
static const Byte kExtractHostOS = NFileHeader::NHostOS::kFAT;
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
static const Byte kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion;
static HRESULT CopyBlock(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
COutArchive &outArchive, ICompressProgressInfo *progress)
{
CMyComPtr<ISequentialOutStream> outStream;
outArchive.CreateStreamForCopying(&outStream);
return CopyBlock(inStream, outStream, progress);
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
static HRESULT WriteRange(IInStream *inStream,
COutArchive &outArchive,
const CUpdateRange &range,
IProgress *progress,
UInt64 &currentComplexity)
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
const CUpdateRange &range, ICompressProgressInfo *progress)
{
UInt64 position;
inStream->Seek(range.Position, STREAM_SEEK_SET, &position);
RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
streamSpec->Init(inStream, range.Size);
streamSpec->SetStream(inStream);
streamSpec->Init(range.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(progress, true);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(localProgress, &currentComplexity, &currentComplexity);
HRESULT result = CopyBlockToArchive(inStreamLimited, outArchive, compressProgress);
currentComplexity += range.Size;
return result;
RINOK(CopyBlockToArchive(inStreamLimited, outArchive, progress));
return progress->SetRatioInfo(&range.Size, &range.Size);
}
static HRESULT UpdateOneFile(IInStream *inStream,
static void SetFileHeader(
COutArchive &archive,
const CCompressionMethodMode &options,
CAddCommon &compressor,
const CUpdateItem &updateItem,
UInt64 &currentComplexity,
IArchiveUpdateCallback *updateCallback,
CItemEx &fileHeader,
CMyComPtr<ISequentialInStream> &fileInStream2)
CItem &item)
{
CMyComPtr<IInStream> fileInStream;
if (fileInStream2)
{
RINOK(fileInStream2.QueryInterface(IID_IInStream, &fileInStream));
}
item.UnPackSize = updateItem.Size;
bool isDirectory;
UInt64 fileSize = updateItem.Size;
fileHeader.UnPackSize = fileSize;
if (updateItem.NewProperties)
{
isDirectory = updateItem.IsDirectory;
fileHeader.Name = updateItem.Name;
fileHeader.ExternalAttributes = updateItem.Attributes;
fileHeader.Time = updateItem.Time;
item.Name = updateItem.Name;
item.ExternalAttributes = updateItem.Attributes;
item.Time = updateItem.Time;
}
else
isDirectory = fileHeader.IsDirectory();
isDirectory = item.IsDirectory();
archive.PrepareWriteCompressedData(fileHeader.Name.Length(), fileSize);
fileHeader.LocalHeaderPosition = archive.GetCurrentPosition();
fileHeader.MadeByVersion.HostOS = kMadeByHostOS;
fileHeader.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
item.LocalHeaderPosition = archive.GetCurrentPosition();
item.MadeByVersion.HostOS = kMadeByHostOS;
item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
fileHeader.ExtractVersion.HostOS = kExtractHostOS;
item.ExtractVersion.HostOS = kExtractHostOS;
fileHeader.InternalAttributes = 0; // test it
fileHeader.ClearFlags();
if(isDirectory)
item.InternalAttributes = 0; // test it
item.ClearFlags();
item.SetEncrypted(!isDirectory && options.PasswordIsDefined);
if (isDirectory)
{
fileHeader.ExtractVersion.Version = kExtractVersionForDirectory;
fileHeader.CompressionMethod = kMethodForDirectory;
fileHeader.PackSize = 0;
fileHeader.FileCRC = 0; // test it
item.ExtractVersion.Version = kExtractVersionForDirectory;
item.CompressionMethod = kMethodForDirectory;
item.PackSize = 0;
item.FileCRC = 0; // test it
}
else
{
{
CSequentialInStreamWithCRC *inSecStreamSpec = 0;
CInStreamWithCRC *inStreamSpec = 0;
CMyComPtr<ISequentialInStream> fileSecInStream;
if (fileInStream)
{
inStreamSpec = new CInStreamWithCRC;
fileSecInStream = inStreamSpec;
inStreamSpec->Init(fileInStream);
}
else
{
inSecStreamSpec = new CSequentialInStreamWithCRC;
fileSecInStream = inSecStreamSpec;
inSecStreamSpec->Init(fileInStream2);
}
CCompressingResult compressingResult;
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(localProgress, &currentComplexity, NULL);
RINOK(compressor.Compress(fileSecInStream, outStream, fileSize, compressProgress, compressingResult));
fileHeader.PackSize = compressingResult.PackSize;
fileHeader.CompressionMethod = compressingResult.Method;
fileHeader.ExtractVersion.Version = compressingResult.ExtractVersion;
if (inStreamSpec != 0)
{
fileHeader.FileCRC = inStreamSpec->GetCRC();
fileHeader.UnPackSize = inStreamSpec->GetSize();
}
else
{
fileHeader.FileCRC = inSecStreamSpec->GetCRC();
fileHeader.UnPackSize = inSecStreamSpec->GetSize();
}
}
}
fileHeader.SetEncrypted(!isDirectory && options.PasswordIsDefined);
/*
fileHeader.CommentSize = (updateItem.Commented) ?
WORD(updateItem.CommentRange.Size) : 0;
*/
fileHeader.LocalExtraSize = 0;
// fileHeader.CentralExtraSize = 0;
RINOK(archive.WriteLocalHeader(fileHeader));
currentComplexity += fileSize;
return updateCallback->SetOperationResult(
NArchive::NUpdate::NOperationResult::kOK);
}
static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult,
bool isAesMode, Byte aesKeyMode, CItem &item)
{
item.ExtractVersion.Version = compressingResult.ExtractVersion;
item.CompressionMethod = compressingResult.Method;
item.FileCRC = compressingResult.CRC;
item.UnPackSize = compressingResult.UnpackSize;
item.PackSize = compressingResult.PackSize;
item.LocalExtra.Clear();
item.CentralExtra.Clear();
if (isAesMode)
{
CWzAesExtraField wzAesField;
wzAesField.Strength = aesKeyMode;
wzAesField.Method = compressingResult.Method;
item.CompressionMethod = NFileHeader::NCompressionMethod::kWzAES;
item.FileCRC = 0;
CExtraSubBlock sb;
wzAesField.SetSubBlock(sb);
item.LocalExtra.SubBlocks.Add(sb);
item.CentralExtra.SubBlocks.Add(sb);
}
}
#ifdef COMPRESS_MT
static DWORD WINAPI CoderThread(void *threadCoderInfo);
struct CThreadInfo
{
NWindows::CThread Thread;
CAutoResetEvent *CompressEvent;
CAutoResetEvent *CompressionCompletedEvent;
bool ExitThread;
CMtCompressProgress *ProgressSpec;
CMyComPtr<ICompressProgressInfo> Progress;
COutMemStream *OutStreamSpec;
CMyComPtr<IOutStream> OutStream;
CMyComPtr<ISequentialInStream> InStream;
CAddCommon Coder;
HRESULT Result;
CCompressingResult CompressingResult;
bool IsFree;
UInt32 UpdateIndex;
CThreadInfo(const CCompressionMethodMode &options):
CompressEvent(NULL),
CompressionCompletedEvent(NULL),
ExitThread(false),
ProgressSpec(0),
OutStreamSpec(0),
Coder(options)
{}
void CreateEvents()
{
CompressEvent = new CAutoResetEvent(false);
CompressionCompletedEvent = new CAutoResetEvent(false);
}
bool CreateThread() { return Thread.Create(CoderThread, this); }
~CThreadInfo();
void WaitAndCode();
void StopWaitClose()
{
ExitThread = true;
if (OutStreamSpec != 0)
OutStreamSpec->StopWriting(E_ABORT);
if (CompressEvent != NULL)
CompressEvent->Set();
Thread.Wait();
Thread.Close();
}
};
CThreadInfo::~CThreadInfo()
{
if (CompressEvent != NULL)
delete CompressEvent;
if (CompressionCompletedEvent != NULL)
delete CompressionCompletedEvent;
}
void CThreadInfo::WaitAndCode()
{
for (;;)
{
CompressEvent->Lock();
if (ExitThread)
return;
Result = Coder.Compress(InStream, OutStream, Progress, CompressingResult);
if (Result == S_OK && Progress)
Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
CompressionCompletedEvent->Set();
}
}
static DWORD WINAPI CoderThread(void *threadCoderInfo)
{
((CThreadInfo *)threadCoderInfo)->WaitAndCode();
return 0;
}
class CThreads
{
public:
CObjectVector<CThreadInfo> Threads;
~CThreads()
{
for (int i = 0; i < Threads.Size(); i++)
Threads[i].StopWaitClose();
}
};
struct CMemBlocks2: public CMemLockBlocks
{
CCompressingResult CompressingResult;
bool Defined;
bool Skip;
CMemBlocks2(): Defined(false), Skip(false) {}
};
class CMemRefs
{
public:
CMemBlockManagerMt *Manager;
CObjectVector<CMemBlocks2> Refs;
CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ;
~CMemRefs()
{
for (int i = 0; i < Refs.Size(); i++)
Refs[i].FreeOpt(Manager);
}
};
#endif
static HRESULT Update2(COutArchive &archive,
CInArchive *inArchive,
IInStream *inStream,
const CObjectVector<CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
@@ -192,6 +260,8 @@ static HRESULT Update2(COutArchive &archive,
IArchiveUpdateCallback *updateCallback)
{
UInt64 complexity = 0;
UInt64 numFilesToCompress = 0;
UInt64 numBytesToCompress = 0;
int i;
for(i = 0; i < updateItems.Size(); i++)
@@ -200,6 +270,8 @@ static HRESULT Update2(COutArchive &archive,
if (updateItem.NewData)
{
complexity += updateItem.Size;
numBytesToCompress += updateItem.Size;
numFilesToCompress++;
/*
if (updateItem.Commented)
complexity += updateItem.CommentRange.Size;
@@ -207,7 +279,9 @@ static HRESULT Update2(COutArchive &archive,
}
else
{
const CItemEx &inputItem = inputItems[updateItem.IndexInArchive];
CItemEx inputItem = inputItems[updateItem.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK)
return E_NOTIMPL;
complexity += inputItem.GetLocalFullSize();
// complexity += inputItem.GetCentralExtraPlusCommentSize();
}
@@ -217,51 +291,345 @@ static HRESULT Update2(COutArchive &archive,
if (comment != 0)
complexity += comment.GetCapacity();
complexity++; // end of central
updateCallback->SetTotal(complexity);
CMyAutoPtr<CAddCommon> compressor;
CAddCommon compressor(*options);
complexity = 0;
CObjectVector<CItem> items;
CRecordVector<UInt32> updateIndices;
for(i = 0; i < updateItems.Size(); i++)
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
#ifdef COMPRESS_MT
const size_t kNumMaxThreads = (1 << 10);
UInt32 numThreads = options->NumThreads;
if (numThreads > kNumMaxThreads)
numThreads = kNumMaxThreads;
const size_t kMemPerThread = (1 << 25);
const size_t kBlockSize = 1 << 16;
CCompressionMethodMode options2;
if (options != 0)
options2 = *options;
bool mtMode = ((options != 0) && (numThreads > 1));
if (numFilesToCompress <= 1)
mtMode = false;
if (mtMode)
{
const CUpdateItem &updateItem = updateItems[i];
RINOK(updateCallback->SetCompleted(&complexity));
Byte method = options->MethodSequence.Front();
if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
mtMode = false;
if (method == NFileHeader::NCompressionMethod::kBZip2)
{
UInt64 averageSize = numBytesToCompress / numFilesToCompress;
UInt32 blockSize = options->DicSize;
if (blockSize == 0)
blockSize = 1;
UInt64 averageNumberOfBlocks = averageSize / blockSize;
UInt32 numBZip2Threads = 32;
if (averageNumberOfBlocks < numBZip2Threads)
numBZip2Threads = (UInt32)averageNumberOfBlocks;
if (numBZip2Threads < 1)
numBZip2Threads = 1;
numThreads = numThreads / numBZip2Threads;
options2.NumThreads = numBZip2Threads;
if (numThreads <= 1)
mtMode = false;
}
}
CMtCompressProgressMixer mtCompressProgressMixer;
mtCompressProgressMixer.Init(numThreads + 1, localProgress);
// we need one item for main stream
CMtCompressProgress *progressMainSpec = new CMtCompressProgress();
CMyComPtr<ICompressProgressInfo> progressMain = progressMainSpec;
progressMainSpec->Init(&mtCompressProgressMixer, (int)numThreads);
CMemBlockManagerMt memManager(kBlockSize);
CMemRefs refs(&memManager);
CThreads threads;
CRecordVector<HANDLE> compressingCompletedEvents;
CRecordVector<int> threadIndices; // list threads in order of updateItems
if (mtMode)
{
if (!memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)))
return E_OUTOFMEMORY;
for(i = 0; i < updateItems.Size(); i++)
refs.Refs.Add(CMemBlocks2());
UInt32 i;
for (i = 0; i < numThreads; i++)
threads.Threads.Add(CThreadInfo(options2));
for (i = 0; i < numThreads; i++)
{
CThreadInfo &threadInfo = threads.Threads[i];
threadInfo.CreateEvents();
threadInfo.OutStreamSpec = new COutMemStream(&memManager);
threadInfo.OutStream = threadInfo.OutStreamSpec;
threadInfo.IsFree = true;
threadInfo.ProgressSpec = new CMtCompressProgress();
threadInfo.Progress = threadInfo.ProgressSpec;
threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i);
if (!threadInfo.CreateThread())
return ::GetLastError();
}
}
int mtItemIndex = 0;
#endif
int itemIndex = 0;
int lastRealStreamItemIndex = -1;
while(itemIndex < updateItems.Size())
{
#ifdef COMPRESS_MT
if (!mtMode)
#endif
{
RINOK(updateCallback->SetCompleted(&complexity));
}
#ifdef COMPRESS_MT
if (mtMode && (UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size())
{
const CUpdateItem &updateItem = updateItems[mtItemIndex++];
if (!updateItem.NewData)
continue;
CItemEx item;
if (updateItem.NewProperties)
{
if (updateItem.IsDirectory)
continue;
}
else
{
item = inputItems[updateItem.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
return E_NOTIMPL;
if (item.IsDirectory())
continue;
}
CMyComPtr<ISequentialInStream> fileInStream;
{
NWindows::NSynchronization::CCriticalSectionLock lock(mtCompressProgressMixer.CriticalSection);
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
if (res == S_FALSE)
{
complexity += updateItem.Size;
complexity++;
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
refs.Refs[mtItemIndex - 1].Skip = true;
continue;
}
RINOK(res);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
for (UInt32 i = 0; i < numThreads; i++)
{
CThreadInfo &threadInfo = threads.Threads[i];
if (threadInfo.IsFree)
{
threadInfo.IsFree = false;
threadInfo.InStream = fileInStream;
threadInfo.OutStreamSpec->Init();
threadInfo.ProgressSpec->Reinit();
threadInfo.CompressEvent->Set();
threadInfo.UpdateIndex = mtItemIndex - 1;
compressingCompletedEvents.Add(*threadInfo.CompressionCompletedEvent);
threadIndices.Add(i);
break;
}
}
continue;
}
if (mtMode)
if (refs.Refs[itemIndex].Skip)
{
itemIndex++;
continue;
}
#endif
const CUpdateItem &updateItem = updateItems[itemIndex];
CItemEx item;
if (!updateItem.NewProperties || !updateItem.NewData)
{
item = inputItems[updateItem.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
return E_NOTIMPL;
}
bool isDirectory;
if (updateItem.NewProperties)
isDirectory = updateItem.IsDirectory;
else
isDirectory = item.IsDirectory();
if (updateItem.NewData)
{
if(compressor.get() == NULL)
#ifdef COMPRESS_MT
if (mtMode && !isDirectory)
{
CMyAutoPtr<CAddCommon> tmp(new CAddCommon(*options));
compressor = tmp;
if (lastRealStreamItemIndex < itemIndex)
{
lastRealStreamItemIndex = itemIndex;
SetFileHeader(archive, *options, updateItem, item);
// file Size can be 64-bit !!!
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
}
CMemBlocks2 &memRef = refs.Refs[itemIndex];
if (memRef.Defined)
{
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
SetItemInfoFromCompressingResult(memRef.CompressingResult,
options->IsAesMode, options->AesKeyMode, item);
SetFileHeader(archive, *options, updateItem, item);
RINOK(archive.WriteLocalHeader(item));
complexity += item.UnPackSize;
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
memRef.FreeOpt(&memManager);
}
else
{
{
CThreadInfo &thread = threads.Threads[threadIndices.Front()];
if (!thread.OutStreamSpec->WasUnlockEventSent())
{
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
thread.OutStreamSpec->SetOutStream(outStream);
thread.OutStreamSpec->SetRealStreamMode();
}
}
DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(),
&compressingCompletedEvents.Front(), FALSE, INFINITE);
int t = (int)(result - WAIT_OBJECT_0);
CThreadInfo &threadInfo = threads.Threads[threadIndices[t]];
threadInfo.InStream.Release();
threadInfo.IsFree = true;
RINOK(threadInfo.Result);
threadIndices.Delete(t);
compressingCompletedEvents.Delete(t);
if (t == 0)
{
RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
threadInfo.OutStreamSpec->ReleaseOutStream();
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
options->IsAesMode, options->AesKeyMode, item);
SetFileHeader(archive, *options, updateItem, item);
RINOK(archive.WriteLocalHeader(item));
complexity += item.UnPackSize;
}
else
{
CMemBlocks2 &memRef = refs.Refs[threadInfo.UpdateIndex];
threadInfo.OutStreamSpec->DetachData(memRef);
memRef.CompressingResult = threadInfo.CompressingResult;
memRef.Defined = true;
continue;
}
}
}
CMyComPtr<ISequentialInStream> fileInStream2;
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream2);
if (res == S_FALSE)
else
#endif
{
complexity += updateItem.Size;
complexity++;
RINOK(updateCallback->SetOperationResult(
NArchive::NUpdate::NOperationResult::kOK));
continue;
{
CMyComPtr<ISequentialInStream> fileInStream;
{
#ifdef COMPRESS_MT
CCriticalSectionLock2 lock;
if (mtMode)
lock.Set(mtCompressProgressMixer.CriticalSection);
#endif
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
if (res == S_FALSE)
{
complexity += updateItem.Size;
complexity++;
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
itemIndex++;
continue;
}
RINOK(res);
#ifdef COMPRESS_MT
if (mtMode)
{
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
#endif
}
// file Size can be 64-bit !!!
SetFileHeader(archive, *options, updateItem, item);
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
if(!isDirectory)
{
CCompressingResult compressingResult;
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
RINOK(compressor.Compress(fileInStream, outStream, compressProgress, compressingResult));
SetItemInfoFromCompressingResult(compressingResult,
options->IsAesMode, options->AesKeyMode, item);
}
}
RINOK(archive.WriteLocalHeader(item));
complexity += item.UnPackSize;
#ifdef COMPRESS_MT
if (!mtMode)
#endif
{
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
}
RINOK(res);
RINOK(UpdateOneFile(inStream, archive, *options,
*compressor, updateItem, complexity, updateCallback, item,
fileInStream2));
}
else
{
// item = inputItems[copyIndices[copyIndexIndex++]];
#ifdef COMPRESS_MT
if (mtMode)
progressMainSpec->Reinit();
#endif
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
ICompressProgressInfo *progress = compressProgress;
#ifdef COMPRESS_MT
if (mtMode)
progress = progressMain;
#endif
if (updateItem.NewProperties)
{
if (item.HasDescriptor())
@@ -275,13 +643,14 @@ static HRESULT Update2(COutArchive &archive,
// Test it
item.Name = updateItem.Name;
item.Time = updateItem.Time;
item.CentralExtra.Clear();
item.LocalExtraSize = 0;
item.CentralExtra.RemoveUnknownSubBlocks();
item.LocalExtra.RemoveUnknownSubBlocks();
archive.PrepareWriteCompressedData2(item.Name.Length(), item.UnPackSize, item.PackSize);
archive.PrepareWriteCompressedData2((UInt16)item.Name.Length(), item.UnPackSize, item.PackSize, item.LocalExtra.HasWzAesField());
item.LocalHeaderPosition = archive.GetCurrentPosition();
archive.SeekToPackedDataPosition();
RINOK(WriteRange(inStream, archive, range, updateCallback, complexity));
RINOK(WriteRange(inStream, archive, range, progress));
complexity += range.Size;
archive.WriteLocalHeader(item);
}
else
@@ -291,15 +660,15 @@ static HRESULT Update2(COutArchive &archive,
// set new header position
item.LocalHeaderPosition = archive.GetCurrentPosition();
RINOK(WriteRange(inStream, archive, range, updateCallback, complexity));
RINOK(WriteRange(inStream, archive, range, progress));
complexity += range.Size;
archive.MoveBasePosition(range.Size);
}
}
items.Add(item);
updateIndices.Add(i);
complexity += NFileHeader::kLocalBlockSize;
itemIndex++;
}
archive.WriteCentralDir(items, comment);
return S_OK;
}
@@ -319,7 +688,11 @@ HRESULT Update(
CInArchiveInfo archiveInfo;
if(inArchive != 0)
{
inArchive->GetArchiveInfo(archiveInfo);
if (archiveInfo.Base != 0)
return E_NOTIMPL;
}
else
archiveInfo.StartPosition = 0;
@@ -336,7 +709,7 @@ HRESULT Update(
if(inArchive != 0)
inStream.Attach(inArchive->CreateStream());
return Update2(outArchive, inStream,
return Update2(outArchive, inArchive, inStream,
inputItems, updateItems,
compressionMethodMode,
archiveInfo.Comment, updateCallback);

Some files were not shown because too many files have changed in this diff Show More