RarHandler.cpp (p7zip_15.14.1_src_all) | : | RarHandler.cpp (p7zip_16.02_src_all) | ||
---|---|---|---|---|
skipping to change at line 221 | skipping to change at line 221 | |||
RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)); | RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)); | |||
AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize); | AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize); | |||
UInt32 blockSize = Get16(buf + 5); | UInt32 blockSize = Get16(buf + 5); | |||
ArcInfo.EncryptVersion = 0; | ArcInfo.EncryptVersion = 0; | |||
ArcInfo.Flags = Get16(buf + 3); | ArcInfo.Flags = Get16(buf + 3); | |||
UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize; | UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize; | |||
/* | ||||
if (ArcInfo.IsThereEncryptVer()) | if (ArcInfo.IsThereEncryptVer()) | |||
{ | { | |||
if (blockSize <= headerSize) | if (blockSize <= headerSize) | |||
return S_FALSE; | return S_FALSE; | |||
RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1)); | RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1)); | |||
AddToSeekValue(1); | AddToSeekValue(1); | |||
ArcInfo.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize]; | ArcInfo.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize]; | |||
headerSize += 1; | headerSize += 1; | |||
} | } | |||
*/ | ||||
if (blockSize < headerSize | if (blockSize < headerSize | |||
|| buf[2] != NHeader::NBlockType::kArchiveHeader | || buf[2] != NHeader::NBlockType::kArchiveHeader | |||
|| !CheckHeaderCrc(buf, headerSize)) | || !CheckHeaderCrc(buf, headerSize)) | |||
return S_FALSE; | return S_FALSE; | |||
size_t commentSize = blockSize - headerSize; | size_t commentSize = blockSize - headerSize; | |||
_comment.Alloc(commentSize); | _comment.Alloc(commentSize); | |||
RINOK(ReadStream_FALSE(stream, _comment, commentSize)); | RINOK(ReadStream_FALSE(stream, _comment, commentSize)); | |||
AddToSeekValue(commentSize); | AddToSeekValue(commentSize); | |||
m_Stream = stream; | m_Stream = stream; | |||
skipping to change at line 509 | skipping to change at line 513 | |||
if (getTextPassword == 0) | if (getTextPassword == 0) | |||
{ | { | |||
error = k_ErrorType_DecryptionError; | error = k_ErrorType_DecryptionError; | |||
return S_OK; // return S_FALSE; | return S_OK; // return S_FALSE; | |||
} | } | |||
if (!m_RarAES) | if (!m_RarAES) | |||
{ | { | |||
m_RarAESSpec = new NCrypto::NRar3::CDecoder; | m_RarAESSpec = new NCrypto::NRar3::CDecoder; | |||
m_RarAES = m_RarAESSpec; | m_RarAES = m_RarAESSpec; | |||
} | } | |||
m_RarAESSpec->SetRar350Mode(ArcInfo.IsEncryptOld()); | // m_RarAESSpec->SetRar350Mode(ArcInfo.IsEncryptOld()); | |||
// Salt | // Salt | |||
const UInt32 kSaltSize = 8; | const UInt32 kSaltSize = 8; | |||
Byte salt[kSaltSize]; | Byte salt[kSaltSize]; | |||
if (!ReadBytesAndTestSize(salt, kSaltSize)) | if (!ReadBytesAndTestSize(salt, kSaltSize)) | |||
return S_FALSE; | return S_FALSE; | |||
m_Position += kSaltSize; | m_Position += kSaltSize; | |||
RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) | RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) | |||
// Password | // Password | |||
CMyComBSTR password; | CMyComBSTR password; | |||
skipping to change at line 951 | skipping to change at line 955 | |||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; | utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; | |||
prop = utcFileTime; | prop = utcFileTime; | |||
} | } | |||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val ue) | STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val ue) | |||
{ | { | |||
COM_TRY_BEGIN | COM_TRY_BEGIN | |||
NCOM::CPropVariant prop; | NCOM::CPropVariant prop; | |||
const CRefItem &refItem = _refItems[index]; | const CRefItem &refItem = _refItems[index]; | |||
const CItem &item = _items[refItem.ItemIndex]; | const CItem &item = _items[refItem.ItemIndex]; | |||
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; | ||||
/* | /* | |||
const CItem *mainItem = &item; | const CItem *mainItem = &item; | |||
if (item.BaseFileIndex >= 0) | if (item.BaseFileIndex >= 0) | |||
mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex]; | mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex]; | |||
*/ | */ | |||
switch (propID) | switch (propID) | |||
{ | { | |||
case kpidPath: | case kpidPath: | |||
{ | { | |||
/* | /* | |||
UString u; | UString u; | |||
if (item.BaseFileIndex >= 0) | if (item.BaseFileIndex >= 0) | |||
u = mainItem->GetName(); | u = mainItem->GetName(); | |||
u += item.GetName(); | u += item.GetName(); | |||
*/ | */ | |||
prop = (const wchar_t *)NItemName::WinNameToOSName(item.GetName()); | prop = (const wchar_t *)NItemName::WinNameToOSName(item.GetName()); | |||
break; | break; | |||
} | } | |||
case kpidIsDir: prop = item.IsDir(); break; | case kpidIsDir: prop = item.IsDir(); break; | |||
case kpidSize: prop = item.Size; break; | case kpidSize: if (lastItem.Is_Size_Defined()) prop = lastItem.Size; break; | |||
case kpidPackSize: prop = GetPackSize(index); break; | case kpidPackSize: prop = GetPackSize(index); break; | |||
case kpidMTime: RarTimeToProp(item.MTime, prop); break; | case kpidMTime: RarTimeToProp(item.MTime, prop); break; | |||
case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); brea k; | case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); brea k; | |||
case kpidATime: if (item.ATimeDefined) RarTimeToProp(item.ATime, prop); brea k; | case kpidATime: if (item.ATimeDefined) RarTimeToProp(item.ATime, prop); brea k; | |||
case kpidAttrib: prop = item.GetWinAttrib(); break; | case kpidAttrib: prop = item.GetWinAttrib(); break; | |||
case kpidEncrypted: prop = item.IsEncrypted(); break; | case kpidEncrypted: prop = item.IsEncrypted(); break; | |||
case kpidSolid: prop = IsSolid(index); break; | case kpidSolid: prop = IsSolid(index); break; | |||
case kpidCommented: prop = item.IsCommented(); break; | case kpidCommented: prop = item.IsCommented(); break; | |||
case kpidSplitBefore: prop = item.IsSplitBefore(); break; | case kpidSplitBefore: prop = item.IsSplitBefore(); break; | |||
case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1] .IsSplitAfter(); break; | case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1] .IsSplitAfter(); break; | |||
case kpidCRC: | case kpidCRC: | |||
{ | { | |||
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; | ||||
prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); | prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); | |||
break; | break; | |||
} | } | |||
case kpidUnpackVer: prop = item.UnPackVersion; break; | case kpidUnpackVer: prop = item.UnPackVersion; break; | |||
case kpidMethod: | case kpidMethod: | |||
{ | { | |||
char s[16]; | char s[16]; | |||
Byte m = item.Method; | Byte m = item.Method; | |||
if (m < (Byte)'0' || m > (Byte)'5') | if (m < (Byte)'0' || m > (Byte)'5') | |||
ConvertUInt32ToString(m, s); | ConvertUInt32ToString(m, s); | |||
skipping to change at line 1373 | skipping to change at line 1378 | |||
// importantTotalPacked = 0; | // importantTotalPacked = 0; | |||
bool allFilesMode = (numItems == (UInt32)(Int32)-1); | bool allFilesMode = (numItems == (UInt32)(Int32)-1); | |||
if (allFilesMode) | if (allFilesMode) | |||
numItems = _refItems.Size(); | numItems = _refItems.Size(); | |||
if (numItems == 0) | if (numItems == 0) | |||
return S_OK; | return S_OK; | |||
unsigned lastIndex = 0; | unsigned lastIndex = 0; | |||
CRecordVector<unsigned> importantIndexes; | CRecordVector<unsigned> importantIndexes; | |||
CRecordVector<bool> extractStatuses; | CRecordVector<bool> extractStatuses; | |||
bool isThereUndefinedSize = false; | ||||
for (UInt32 t = 0; t < numItems; t++) | for (UInt32 t = 0; t < numItems; t++) | |||
{ | { | |||
unsigned index = allFilesMode ? t : indices[t]; | unsigned index = allFilesMode ? t : indices[t]; | |||
const CRefItem &refItem = _refItems[index]; | ||||
const CItem &item = _items[refItem.ItemIndex]; | { | |||
censoredTotalUnPacked += item.Size; | const CRefItem &refItem = _refItems[index]; | |||
// censoredTotalPacked += item.PackSize; | const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; | |||
if (item.Is_Size_Defined()) | ||||
censoredTotalUnPacked += item.Size; | ||||
else | ||||
isThereUndefinedSize = true; | ||||
// censoredTotalPacked += item.PackSize; | ||||
} | ||||
unsigned j; | unsigned j; | |||
for (j = lastIndex; j <= index; j++) | for (j = lastIndex; j <= index; j++) | |||
// if (!_items[_refItems[j].ItemIndex].IsSolid()) | // if (!_items[_refItems[j].ItemIndex].IsSolid()) | |||
if (!IsSolid(j)) | if (!IsSolid(j)) | |||
lastIndex = j; | lastIndex = j; | |||
for (j = lastIndex; j <= index; j++) | for (j = lastIndex; j <= index; j++) | |||
{ | { | |||
const CRefItem &refItem = _refItems[j]; | const CRefItem &refItem = _refItems[j]; | |||
const CItem &item = _items[refItem.ItemIndex]; | const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; | |||
// const CItem &item = _items[j]; | if (item.Is_Size_Defined()) | |||
importantTotalUnPacked += item.Size; | ||||
importantTotalUnPacked += item.Size; | else | |||
isThereUndefinedSize = true; | ||||
// importantTotalPacked += item.PackSize; | // importantTotalPacked += item.PackSize; | |||
importantIndexes.Add(j); | importantIndexes.Add(j); | |||
extractStatuses.Add(j == index); | extractStatuses.Add(j == index); | |||
} | } | |||
lastIndex = index + 1; | lastIndex = index + 1; | |||
} | } | |||
RINOK(extractCallback->SetTotal(importantTotalUnPacked)); | if (importantTotalUnPacked != 0 || !isThereUndefinedSize) | |||
{ | ||||
RINOK(extractCallback->SetTotal(importantTotalUnPacked)); | ||||
} | ||||
UInt64 currentImportantTotalUnPacked = 0; | UInt64 currentImportantTotalUnPacked = 0; | |||
UInt64 currentImportantTotalPacked = 0; | UInt64 currentImportantTotalPacked = 0; | |||
UInt64 currentUnPackSize, currentPackSize; | UInt64 currentUnPackSize, currentPackSize; | |||
CObjectVector<CMethodItem> methodItems; | CObjectVector<CMethodItem> methodItems; | |||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; | NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; | |||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; | CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; | |||
CFilterCoder *filterStreamSpec = new CFilterCoder(false); | CFilterCoder *filterStreamSpec = new CFilterCoder(false); | |||
skipping to change at line 1426 | skipping to change at line 1449 | |||
CMyComPtr<ICompressFilter> rar3CryptoDecoder; | CMyComPtr<ICompressFilter> rar3CryptoDecoder; | |||
CVolsInStream *volsInStreamSpec = NULL; | CVolsInStream *volsInStreamSpec = NULL; | |||
CMyComPtr<ISequentialInStream> volsInStream; | CMyComPtr<ISequentialInStream> volsInStream; | |||
CLocalProgress *lps = new CLocalProgress; | CLocalProgress *lps = new CLocalProgress; | |||
CMyComPtr<ICompressProgressInfo> progress = lps; | CMyComPtr<ICompressProgressInfo> progress = lps; | |||
lps->Init(extractCallback, false); | lps->Init(extractCallback, false); | |||
bool solidStart = true; | bool solidStart = true; | |||
for (unsigned i = 0; i < importantIndexes.Size(); i++, | ||||
for (unsigned i = 0;; | ||||
i++, | ||||
currentImportantTotalUnPacked += currentUnPackSize, | currentImportantTotalUnPacked += currentUnPackSize, | |||
currentImportantTotalPacked += currentPackSize) | currentImportantTotalPacked += currentPackSize) | |||
{ | { | |||
lps->InSize = currentImportantTotalPacked; | lps->InSize = currentImportantTotalPacked; | |||
lps->OutSize = currentImportantTotalUnPacked; | lps->OutSize = currentImportantTotalUnPacked; | |||
RINOK(lps->SetCur()); | RINOK(lps->SetCur()); | |||
if (i >= importantIndexes.Size()) | ||||
break; | ||||
CMyComPtr<ISequentialOutStream> realOutStream; | CMyComPtr<ISequentialOutStream> realOutStream; | |||
Int32 askMode; | Int32 askMode; | |||
if (extractStatuses[i]) | if (extractStatuses[i]) | |||
askMode = testMode ? | askMode = testMode ? | |||
NExtract::NAskMode::kTest : | NExtract::NAskMode::kTest : | |||
NExtract::NAskMode::kExtract; | NExtract::NAskMode::kExtract; | |||
else | else | |||
askMode = NExtract::NAskMode::kSkip; | askMode = NExtract::NAskMode::kSkip; | |||
UInt32 index = importantIndexes[i]; | UInt32 index = importantIndexes[i]; | |||
const CRefItem &refItem = _refItems[index]; | const CRefItem &refItem = _refItems[index]; | |||
const CItem &item = _items[refItem.ItemIndex]; | const CItem &item = _items[refItem.ItemIndex]; | |||
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; | ||||
currentUnPackSize = item.Size; | UInt64 outSize = (UInt64)(Int64)-1; | |||
currentUnPackSize = 0; | ||||
if (lastItem.Is_Size_Defined()) | ||||
{ | ||||
outSize = lastItem.Size; | ||||
currentUnPackSize = outSize; | ||||
} | ||||
currentPackSize = GetPackSize(index); | currentPackSize = GetPackSize(index); | |||
if (item.IgnoreItem()) | if (item.IgnoreItem()) | |||
continue; | continue; | |||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); | RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); | |||
if (!IsSolid(index)) | if (!IsSolid(index)) | |||
solidStart = true; | solidStart = true; | |||
skipping to change at line 1515 | skipping to change at line 1551 | |||
{ | { | |||
// CMyComPtr<ICryptoSetPassword> cryptoSetPassword; | // CMyComPtr<ICryptoSetPassword> cryptoSetPassword; | |||
if (item.UnPackVersion >= 29) | if (item.UnPackVersion >= 29) | |||
{ | { | |||
if (!rar3CryptoDecoder) | if (!rar3CryptoDecoder) | |||
{ | { | |||
rar3CryptoDecoderSpec = new NCrypto::NRar3::CDecoder; | rar3CryptoDecoderSpec = new NCrypto::NRar3::CDecoder; | |||
rar3CryptoDecoder = rar3CryptoDecoderSpec; | rar3CryptoDecoder = rar3CryptoDecoderSpec; | |||
} | } | |||
rar3CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); | // rar3CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); | |||
/* | /* | |||
CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties; | CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties; | |||
RINOK(rar3CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties 2, | RINOK(rar3CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties 2, | |||
&cryptoProperties)); | &cryptoProperties)); | |||
*/ | */ | |||
RINOK(rar3CryptoDecoderSpec->SetDecoderProperties2(item.Salt, item.HasSa lt() ? sizeof(item.Salt) : 0)); | RINOK(rar3CryptoDecoderSpec->SetDecoderProperties2(item.Salt, item.HasSa lt() ? sizeof(item.Salt) : 0)); | |||
filterStreamSpec->Filter = rar3CryptoDecoder; | filterStreamSpec->Filter = rar3CryptoDecoder; | |||
} | } | |||
else if (item.UnPackVersion >= 20) | else if (item.UnPackVersion >= 20) | |||
{ | { | |||
skipping to change at line 1565 | skipping to change at line 1601 | |||
RINOK(getTextPassword->CryptoGetTextPassword(&password)); | RINOK(getTextPassword->CryptoGetTextPassword(&password)); | |||
if (item.UnPackVersion >= 29) | if (item.UnPackVersion >= 29) | |||
{ | { | |||
unsigned len = 0; | unsigned len = 0; | |||
if (password) | if (password) | |||
len = MyStringLen(password); | len = MyStringLen(password); | |||
if (len > kPasswordLen_MAX) | if (len > kPasswordLen_MAX) | |||
len = kPasswordLen_MAX; | len = kPasswordLen_MAX; | |||
CByteArr buffer(len * 2); | CByteArr buffer(len * 2); | |||
for (unsigned i = 0; i < len; i++) | for (unsigned k = 0; k < len; k++) | |||
{ | { | |||
wchar_t c = password[i]; | wchar_t c = password[k]; | |||
((Byte *)buffer)[i * 2] = (Byte)c; | ((Byte *)buffer)[k * 2] = (Byte)c; | |||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); | ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); | |||
} | } | |||
rar3CryptoDecoderSpec->SetPassword((const Byte *)buffer, len * 2); | rar3CryptoDecoderSpec->SetPassword((const Byte *)buffer, len * 2); | |||
} | } | |||
else | else | |||
{ | { | |||
AString oemPassword; | AString oemPassword; | |||
if (password) | if (password) | |||
{ | { | |||
UString unicode = (LPCOLESTR)password; | UString unicode = (LPCOLESTR)password; | |||
if (unicode.Len() > kPasswordLen_MAX) | if (unicode.Len() > kPasswordLen_MAX) | |||
skipping to change at line 1672 | skipping to change at line 1708 | |||
commonCoder = decoder; | commonCoder = decoder; | |||
break; | break; | |||
} | } | |||
default: | default: | |||
outStream.Release(); | outStream.Release(); | |||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kU nsupportedMethod)); | RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kU nsupportedMethod)); | |||
continue; | continue; | |||
} | } | |||
HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Siz e, progress); | HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &outSize, progress); | |||
if (item.IsEncrypted()) | if (item.IsEncrypted()) | |||
filterStreamSpec->ReleaseInStream(); | filterStreamSpec->ReleaseInStream(); | |||
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; | if (outSize == (UInt64)(Int64)-1) | |||
currentUnPackSize = outStreamSpec->GetSize(); | ||||
int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastIte m.FileCRC) ? | int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastIte m.FileCRC) ? | |||
NExtract::NOperationResult::kOK: | NExtract::NOperationResult::kOK: | |||
NExtract::NOperationResult::kCRCError; | NExtract::NOperationResult::kCRCError; | |||
outStream.Release(); | outStream.Release(); | |||
if (result != S_OK) | if (result != S_OK) | |||
{ | { | |||
if (result == S_FALSE) | if (result == S_FALSE) | |||
opRes = NExtract::NOperationResult::kDataError; | opRes = NExtract::NOperationResult::kDataError; | |||
else if (result == E_NOTIMPL) | else if (result == E_NOTIMPL) | |||
End of changes. 22 change blocks. | ||||
21 lines changed or deleted | 59 lines changed or added |