mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 22:11:38 -06:00
4.27 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
31e7b924e8
commit
d66cf2fcf3
@@ -46,9 +46,9 @@ DEFINE_GUID(CLSID_CCryptoRar29Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
// {23170F69-40C1-278A-1000-000110020000}
|
||||
// {23170F69-40C1-278A-1000-000110030000}
|
||||
DEFINE_GUID(CLSID_CRarHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
|
||||
@@ -178,6 +178,14 @@ SOURCE=..\..\..\Common\Types.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\UTFConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\UTFConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -400,6 +408,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7z"
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
if (item.HasUnicodeName())
|
||||
if (item.HasUnicodeName() && !item.UnicodeName.IsEmpty())
|
||||
propVariant = item.UnicodeName;
|
||||
else
|
||||
propVariant = (const wchar_t *)MultiByteToUnicodeString(item.Name, CP_OEMCP);
|
||||
@@ -615,6 +615,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec;
|
||||
CMyComPtr<ICompressFilter> rar20CryptoDecoder;
|
||||
NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec;
|
||||
CMyComPtr<ICompressFilter> rar29CryptoDecoder;
|
||||
|
||||
CFolderInStream *folderInStreamSpec = NULL;
|
||||
@@ -727,9 +728,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
if (!rar29CryptoDecoder)
|
||||
{
|
||||
rar29CryptoDecoder = new NCrypto::NRar29::CDecoder;
|
||||
rar29CryptoDecoderSpec = new NCrypto::NRar29::CDecoder;
|
||||
rar29CryptoDecoder = rar29CryptoDecoderSpec;
|
||||
// RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder));
|
||||
}
|
||||
rar29CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36);
|
||||
CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties;
|
||||
RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2,
|
||||
&cryptoProperties));
|
||||
|
||||
@@ -42,7 +42,10 @@ namespace NArchive
|
||||
const UInt16 kRecovery = 0x40;
|
||||
const UInt16 kBlockEncryption = 0x80;
|
||||
const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later)
|
||||
const UInt16 kEncryptVer = 0x200; // RAR 3.6 there is EncryptVer Byte in End of MainHeader
|
||||
|
||||
const int kHeaderSizeMin = 7;
|
||||
|
||||
struct CBlock
|
||||
{
|
||||
UInt16 CRC;
|
||||
@@ -53,9 +56,19 @@ namespace NArchive
|
||||
UInt32 Reserved2;
|
||||
// UInt16 GetRealCRC() const;
|
||||
};
|
||||
|
||||
const int kArchiveHeaderSize = 13;
|
||||
|
||||
const int kBlockHeadersAreEncrypted = 0x80;
|
||||
|
||||
struct CHeader360: public CBlock
|
||||
{
|
||||
Byte EncryptVersion;
|
||||
bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; }
|
||||
bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; }
|
||||
bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
|
||||
UInt32 GetBaseSize() const { return kArchiveHeaderSize + (IsEncryptOld() ? 0 : 1); }
|
||||
};
|
||||
}
|
||||
|
||||
namespace NFile
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/CRC.h"
|
||||
#include "Common/UTFConvert.h"
|
||||
|
||||
#include "RarIn.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NRar {
|
||||
@@ -115,7 +117,7 @@ bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
|
||||
return (i == size);
|
||||
}
|
||||
UInt32 processedSize;
|
||||
m_Stream->Read(data, size, &processedSize);
|
||||
ReadStream(m_Stream, data, size, &processedSize);
|
||||
return (processedSize == size);
|
||||
}
|
||||
|
||||
@@ -128,7 +130,7 @@ void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size)
|
||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = m_Stream->Read(data, size, &realProcessedSize);
|
||||
HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
AddToSeekValue(realProcessedSize);
|
||||
@@ -155,6 +157,7 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
|
||||
m_ArchiveHeader.Size = ReadUInt16();
|
||||
m_ArchiveHeader.Reserved1 = ReadUInt16();
|
||||
m_ArchiveHeader.Reserved2 = ReadUInt32();
|
||||
m_ArchiveHeader.EncryptVersion = 0;
|
||||
|
||||
CCRC crc;
|
||||
crc.UpdateByte(m_ArchiveHeader.Type);
|
||||
@@ -163,6 +166,14 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
|
||||
crc.UpdateUInt16(m_ArchiveHeader.Reserved1);
|
||||
crc.UpdateUInt32(m_ArchiveHeader.Reserved2);
|
||||
|
||||
if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize)
|
||||
{
|
||||
ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize);
|
||||
if (processedSize != 1)
|
||||
return false;
|
||||
crc.UpdateByte(m_ArchiveHeader.EncryptVersion);
|
||||
}
|
||||
|
||||
UInt32 u = crc.GetDigest();
|
||||
if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF))
|
||||
ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError);
|
||||
@@ -177,7 +188,7 @@ void CInArchive::SkipArchiveComment()
|
||||
{
|
||||
if (!m_SeekOnArchiveComment)
|
||||
return;
|
||||
AddToSeekValue(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize);
|
||||
AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize());
|
||||
m_SeekOnArchiveComment = false;
|
||||
}
|
||||
|
||||
@@ -256,15 +267,18 @@ void CInArchive::ReadName(CItemEx &item, int nameSize)
|
||||
buffer[mainLen] = '\0';
|
||||
item.Name = buffer;
|
||||
|
||||
int unicodeNameSizeMax = MyMin(nameSize, (0x400));
|
||||
_unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
|
||||
|
||||
if((m_BlockHeader.Flags & NHeader::NFile::kUnicodeName) != 0 &&
|
||||
mainLen < nameSize)
|
||||
if(item.HasUnicodeName())
|
||||
{
|
||||
DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1,
|
||||
nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
|
||||
item.UnicodeName = _unicodeNameBuffer;
|
||||
if(mainLen < nameSize)
|
||||
{
|
||||
int unicodeNameSizeMax = MyMin(nameSize, (0x400));
|
||||
_unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
|
||||
DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1,
|
||||
nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
|
||||
item.UnicodeName = _unicodeNameBuffer;
|
||||
}
|
||||
else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName))
|
||||
item.UnicodeName.Empty();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -398,6 +412,8 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
m_RarAESSpec = new NCrypto::NRar29::CDecoder;
|
||||
m_RarAES = m_RarAESSpec;
|
||||
}
|
||||
m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld());
|
||||
|
||||
// Salt
|
||||
const UInt32 kSaltSize = 8;
|
||||
Byte salt[kSaltSize];
|
||||
@@ -410,9 +426,17 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password))
|
||||
UString unicodePassword(password);
|
||||
|
||||
RINOK(m_RarAESSpec->CryptoSetPassword(
|
||||
(const Byte *)(const wchar_t *)unicodePassword,
|
||||
unicodePassword.Length() * 2));
|
||||
CByteBuffer buffer;
|
||||
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < unicodePassword.Length(); i++)
|
||||
{
|
||||
wchar_t c = unicodePassword[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
|
||||
RINOK(m_RarAESSpec->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||
|
||||
const UInt32 kDecryptedBufferSize = (1 << 12);
|
||||
if (m_DecryptedData.GetCapacity() == 0)
|
||||
@@ -420,7 +444,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
m_DecryptedData.SetCapacity(kDecryptedBufferSize);
|
||||
}
|
||||
RINOK(m_RarAES->Init());
|
||||
RINOK(m_Stream->Read((Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize));
|
||||
RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize));
|
||||
m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize);
|
||||
|
||||
m_CryptoMode = true;
|
||||
@@ -486,7 +510,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
|
||||
void CInArchive::DirectGetBytes(void *data, UInt32 size)
|
||||
{
|
||||
m_Stream->Read(data, size, NULL);
|
||||
ReadStream(m_Stream, data, size, NULL);
|
||||
}
|
||||
|
||||
bool CInArchive::SeekInArchive(UInt64 position)
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
|
||||
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }
|
||||
bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; }
|
||||
bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; }
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
@@ -51,7 +52,7 @@ class CInArchive
|
||||
UInt64 m_Position;
|
||||
UInt64 m_ArchiveStartPosition;
|
||||
|
||||
NHeader::NArchive::CBlock m_ArchiveHeader;
|
||||
NHeader::NArchive::CHeader360 m_ArchiveHeader;
|
||||
CDynamicBuffer<char> m_NameBuffer;
|
||||
CDynamicBuffer<wchar_t> _unicodeNameBuffer;
|
||||
bool m_SeekOnArchiveComment;
|
||||
|
||||
@@ -64,6 +64,7 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
|
||||
}
|
||||
realProcessedSize += localProcessedSize;
|
||||
size -= localProcessedSize;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -75,9 +76,4 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Read(data, size, processedSize);
|
||||
}
|
||||
|
||||
}}
|
||||
}}
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
private:
|
||||
CObjectVector<CInArchive> *_archives;
|
||||
|
||||
@@ -18,6 +18,7 @@ COMMON_OBJS = \
|
||||
$O\NewHandler.obj \
|
||||
$O\String.obj \
|
||||
$O\StringConvert.obj \
|
||||
$O\UTFConvert.obj \
|
||||
$O\Vector.obj \
|
||||
|
||||
WIN_OBJS = \
|
||||
@@ -29,6 +30,7 @@ WIN_OBJS = \
|
||||
$O\LimitedStreams.obj \
|
||||
$O\ProgressUtils.obj \
|
||||
$O\StreamObjects.obj \
|
||||
$O\StreamUtils.obj \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O\CodecsPath.obj \
|
||||
|
||||
Reference in New Issue
Block a user