Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/Rar/RarIn.cpp')
-rwxr-xr-xCPP/7zip/Archive/Rar/RarIn.cpp158
1 files changed, 61 insertions, 97 deletions
diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp
index efb87fb7..18669405 100755
--- a/CPP/7zip/Archive/Rar/RarIn.cpp
+++ b/CPP/7zip/Archive/Rar/RarIn.cpp
@@ -9,9 +9,11 @@
#include "../../Common/LimitedStreams.h"
#include "../../Common/StreamUtils.h"
-extern "C"
-{
- #include "../../../../C/7zCrc.h"
+#include "../Common/FindSignature.h"
+
+extern "C"
+{
+ #include "../../../../C/7zCrc.h"
}
namespace NArchive {
@@ -23,17 +25,18 @@ void CInArchive::ThrowExceptionWithCode(
throw CInArchiveException(cause);
}
-bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
+HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
{
- m_CryptoMode = false;
- if(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK)
- return false;
- m_Position = m_StreamStartPosition;
- m_Stream = inStream;
- if (ReadMarkerAndArchiveHeader(searchHeaderSizeLimit))
- return true;
- m_Stream.Release();
- return false;
+ try
+ {
+ Close();
+ HRESULT res = Open2(inStream, searchHeaderSizeLimit);
+ if (res == S_OK)
+ return res;
+ Close();
+ return res;
+ }
+ catch(...) { Close(); throw; }
}
void CInArchive::Close()
@@ -50,56 +53,14 @@ static inline bool TestMarkerCandidate(const void *aTestBytes)
return true;
}
-bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
+HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
- // if (m_Length < NHeader::kMarkerSize)
- // return false;
- m_ArchiveStartPosition = 0;
- m_Position = m_StreamStartPosition;
- if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
- return false;
-
- Byte marker[NHeader::kMarkerSize];
- UInt32 processedSize;
- ReadBytes(marker, NHeader::kMarkerSize, &processedSize);
- if(processedSize != NHeader::kMarkerSize)
- return false;
- if (TestMarkerCandidate(marker))
- return true;
-
- CByteDynamicBuffer dynamicBuffer;
- static const UInt32 kSearchMarkerBufferSize = 0x10000;
- dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize);
- Byte *buffer = dynamicBuffer;
- UInt32 numBytesPrev = NHeader::kMarkerSize - 1;
- memmove(buffer, marker + 1, numBytesPrev);
- UInt64 curTestPos = m_StreamStartPosition + 1;
- for (;;)
- {
- if (searchHeaderSizeLimit != NULL)
- if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
- break;
- UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
- ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
- UInt32 numBytesInBuffer = numBytesPrev + processedSize;
- if (numBytesInBuffer < NHeader::kMarkerSize)
- break;
- UInt32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1;
- for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
- {
- if (TestMarkerCandidate(buffer + pos))
- {
- m_ArchiveStartPosition = curTestPos;
- m_Position = curTestPos + NHeader::kMarkerSize;
- if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK)
- return false;
- return true;
- }
- }
- numBytesPrev = numBytesInBuffer - numTests;
- memmove(buffer, buffer + numTests, numBytesPrev);
- }
- return false;
+ RINOK(FindSignatureInStream(stream,
+ NHeader::kMarker, NHeader::kMarkerSize,
+ searchHeaderSizeLimit, m_ArchiveStartPosition));
+ m_Stream = stream;
+ m_Position = m_ArchiveStartPosition + NHeader::kMarkerSize;
+ return m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL);
}
void CInArchive::ThrowUnexpectedEndOfArchiveException()
@@ -154,18 +115,21 @@ static UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 v)
}
-bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
+HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
- if (!FindAndReadMarker(searchHeaderSizeLimit))
- return false;
+ m_CryptoMode = false;
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition));
+ m_Position = m_StreamStartPosition;
+
+ RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit));
Byte buf[NHeader::NArchive::kArchiveHeaderSize];
UInt32 processedSize;
ReadBytes(buf, sizeof(buf), &processedSize);
if (processedSize != sizeof(buf))
- return false;
+ return S_FALSE;
m_CurData = buf;
- m_CurPos = 0;
+ m_CurPos = 0;
m_PosLimit = sizeof(buf);
m_ArchiveHeader.CRC = ReadUInt16();
@@ -187,17 +151,17 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
{
ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize);
if (processedSize != 1)
- return false;
+ return S_FALSE;
crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion);
}
if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF))
ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError);
if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader)
- return false;
+ return S_FALSE;
m_ArchiveCommentPosition = m_Position;
m_SeekOnArchiveComment = true;
- return true;
+ return S_OK;
}
void CInArchive::SkipArchiveComment()
@@ -216,7 +180,7 @@ void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
archiveInfo.CommentSize = (UInt16)(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize);
}
-static void DecodeUnicodeFileName(const char *name, const Byte *encName,
+static void DecodeUnicodeFileName(const char *name, const Byte *encName,
int encSize, wchar_t *unicodeName, int maxDecSize)
{
int encPos = 0;
@@ -249,7 +213,7 @@ static void DecodeUnicodeFileName(const char *name, const Byte *encName,
if (length & 0x80)
{
Byte correction = encName[encPos++];
- for (length = (length & 0x7f) + 2;
+ for (length = (length & 0x7f) + 2;
length > 0 && decPos < maxDecSize; length--, decPos++)
unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8));
}
@@ -289,7 +253,7 @@ void CInArchive::ReadName(CItemEx &item, int nameSize)
{
int unicodeNameSizeMax = MyMin(nameSize, (0x400));
_unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
- DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1,
+ DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1,
nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
item.UnicodeName = _unicodeNameBuffer;
}
@@ -341,26 +305,26 @@ void CInArchive::ReadTime(Byte mask, CRarTime &rarTime)
void CInArchive::ReadHeaderReal(CItemEx &item)
{
- item.Flags = m_BlockHeader.Flags;
+ item.Flags = m_BlockHeader.Flags;
item.PackSize = ReadUInt32();
- item.UnPackSize = ReadUInt32();
+ item.Size = ReadUInt32();
item.HostOS = ReadByte();
item.FileCRC = ReadUInt32();
- item.LastWriteTime.DosTime = ReadUInt32();
+ item.MTime.DosTime = ReadUInt32();
item.UnPackVersion = ReadByte();
item.Method = ReadByte();
int nameSize = ReadUInt16();
- item.Attributes = ReadUInt32();
+ item.Attrib = ReadUInt32();
- item.LastWriteTime.LowSecond = 0;
- item.LastWriteTime.SubTime[0] =
- item.LastWriteTime.SubTime[1] =
- item.LastWriteTime.SubTime[2] = 0;
+ item.MTime.LowSecond = 0;
+ item.MTime.SubTime[0] =
+ item.MTime.SubTime[1] =
+ item.MTime.SubTime[2] = 0;
if((item.Flags & NHeader::NFile::kSize64Bits) != 0)
{
item.PackSize |= ((UInt64)ReadUInt32() << 32);
- item.UnPackSize |= ((UInt64)ReadUInt32() << 32);
+ item.Size |= ((UInt64)ReadUInt32() << 32);
}
ReadName(item, nameSize);
@@ -377,18 +341,18 @@ void CInArchive::ReadHeaderReal(CItemEx &item)
Byte modifMask = (Byte)(b >> 4);
Byte createMask = (Byte)(b & 0xF);
if ((modifMask & 8) != 0)
- ReadTime(modifMask, item.LastWriteTime);
- item.IsCreationTimeDefined = ((createMask & 8) != 0);
- if (item.IsCreationTimeDefined)
+ ReadTime(modifMask, item.MTime);
+ item.CTimeDefined = ((createMask & 8) != 0);
+ if (item.CTimeDefined)
{
- item.CreationTime.DosTime = ReadUInt32();
- ReadTime(createMask, item.CreationTime);
+ item.CTime.DosTime = ReadUInt32();
+ ReadTime(createMask, item.CTime);
}
- item.IsLastAccessTimeDefined = ((accessMask & 8) != 0);
- if (item.IsLastAccessTimeDefined)
+ item.ATimeDefined = ((accessMask & 8) != 0);
+ if (item.ATimeDefined)
{
- item.LastAccessTime.DosTime = ReadUInt32();
- ReadTime(accessMask, item.LastAccessTime);
+ item.ATime.DosTime = ReadUInt32();
+ ReadTime(accessMask, item.ATime);
}
}
@@ -418,7 +382,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
{
if(!SeekInArchive(m_Position))
return S_FALSE;
- if (!m_CryptoMode && (m_ArchiveHeader.Flags &
+ if (!m_CryptoMode && (m_ArchiveHeader.Flags &
NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
{
m_CryptoMode = false;
@@ -487,23 +451,23 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
if (m_BlockHeader.HeadSize < 7)
ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive);
- if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive)
+ if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive)
return S_FALSE;
- if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader)
+ if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader)
{
m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize);
m_CurData = (Byte *)m_FileHeaderData;
m_PosLimit = m_BlockHeader.HeadSize;
ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7);
- ReadHeaderReal(item);
- if ((CrcCalc(m_CurData + 2,
+ ReadHeaderReal(item);
+ if ((CrcCalc(m_CurData + 2,
m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC)
ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError);
FinishCryptoBlock();
m_CryptoMode = false;
- SeekInArchive(m_Position); // Move Position to compressed Data;
+ SeekInArchive(m_Position); // Move Position to compressed Data;
AddToSeekValue(item.PackSize); // m_Position points to next header;
return S_OK;
}