This commit is contained in:
Igor Pavlov
2010-11-11 00:00:00 +00:00
committed by Kornel Lesiński
parent c65230d858
commit b75af1bba6
25 changed files with 314 additions and 275 deletions

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 9 #define MY_VER_MAJOR 9
#define MY_VER_MINOR 18 #define MY_VER_MINOR 19
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION "9.18 beta" #define MY_VERSION "9.19 beta"
#define MY_DATE "2010-11-02" #define MY_DATE "2010-11-11"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE

View File

@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup /* SfxSetup.c - 7z SFX Setup
2010-11-02 : Igor Pavlov : Public domain */ 2010-11-11 : Igor Pavlov : Public domain */
#ifndef UNICODE #ifndef UNICODE
#define UNICODE #define UNICODE
@@ -530,10 +530,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#ifndef UNDER_CE #ifndef UNDER_CE
| SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_DDEWAIT
#endif #endif
/* | SEE_MASK_NO_CONSOLE */
; ;
if (wcslen(cmdLineParams) != 0) if (wcslen(cmdLineParams) != 0)
ei.lpParameters = cmdLineParams; ei.lpParameters = cmdLineParams;
ei.nShow = SW_SHOWNORMAL; ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */
success = ShellExecuteEx(&ei); success = ShellExecuteEx(&ei);
executeRes = (UINT32)(UINT_PTR)ei.hInstApp; executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */ if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */

View File

@@ -7,6 +7,7 @@
#include "Common/StringConvert.h" #include "Common/StringConvert.h"
#include "Windows/PropVariant.h" #include "Windows/PropVariant.h"
#include "Windows/PropVariantUtils.h"
#include "Windows/Time.h" #include "Windows/Time.h"
#include "../../IPassword.h" #include "../../IPassword.h"
@@ -46,6 +47,20 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown"; static const wchar_t *kUnknownOS = L"Unknown";
static const CUInt32PCharPair k_Flags[] =
{
{ 0, "Volume" },
{ 1, "Comment" },
{ 2, "Lock" },
{ 3, "Solid" },
{ 4, "NewVolName" }, // pack_comment in old versuons
{ 5, "Authenticity" },
{ 6, "Recovery" },
{ 7, "BlockEncryption" },
{ 8, "FirstVolume" },
{ 9, "EncryptVer" }
};
static const STATPROPSTG kProps[] = static const STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
@@ -70,6 +85,7 @@ static const STATPROPSTG kProps[] =
static const STATPROPSTG kArcProps[] = static const STATPROPSTG kArcProps[] =
{ {
{ NULL, kpidCharacts, VT_BSTR},
{ NULL, kpidSolid, VT_BOOL}, { NULL, kpidSolid, VT_BOOL},
{ NULL, kpidNumBlocks, VT_UI4}, { NULL, kpidNumBlocks, VT_UI4},
// { NULL, kpidEncrypted, VT_BOOL}, // { NULL, kpidEncrypted, VT_BOOL},
@@ -98,6 +114,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
switch(propID) switch(propID)
{ {
case kpidSolid: prop = _archiveInfo.IsSolid(); break; case kpidSolid: prop = _archiveInfo.IsSolid(); break;
case kpidCharacts: FLAGS_TO_PROP(k_Flags, _archiveInfo.Flags, prop); break;
// case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break; // it's for encrypted names. // case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break; // it's for encrypted names.
case kpidIsVolume: prop = _archiveInfo.IsVolume(); break; case kpidIsVolume: prop = _archiveInfo.IsVolume(); break;
case kpidNumVolumes: prop = (UInt32)_archives.Size(); break; case kpidNumVolumes: prop = (UInt32)_archives.Size(); break;
@@ -325,19 +342,19 @@ public:
HRESULT CHandler::Open2(IInStream *stream, HRESULT CHandler::Open2(IInStream *stream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *openCallback)
{ {
{ {
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<ICryptoGetTextPassword> getTextPassword;
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openCallback;
CVolumeName seqName; CVolumeName seqName;
UInt64 totalBytes = 0; UInt64 totalBytes = 0;
UInt64 curBytes = 0; UInt64 curBytes = 0;
if (openArchiveCallback != NULL) if (openCallback)
{ {
openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
@@ -379,12 +396,12 @@ HRESULT CHandler::Open2(IInStream *stream,
inStream = stream; inStream = stream;
UInt64 endPos = 0; UInt64 endPos = 0;
if (openArchiveCallback != NULL) RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
if (openCallback)
{ {
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
totalBytes += endPos; totalBytes += endPos;
RINOK(openArchiveCallback->SetTotal(NULL, &totalBytes)); RINOK(openCallback->SetTotal(NULL, &totalBytes));
} }
NArchive::NRar::CInArchive archive; NArchive::NRar::CInArchive archive;
@@ -396,15 +413,16 @@ HRESULT CHandler::Open2(IInStream *stream,
CItemEx item; CItemEx item;
for (;;) for (;;)
{ {
if (archive.m_Position > endPos)
{
AddErrorMessage("Unexpected end of archive");
break;
}
bool decryptionError; bool decryptionError;
AString errorMessageLoc; AString errorMessageLoc;
HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError, errorMessageLoc); HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError, errorMessageLoc);
if (errorMessageLoc) if (errorMessageLoc)
{ AddErrorMessage(errorMessageLoc);
if (!_errorMessage.IsEmpty())
_errorMessage += '\n';
_errorMessage += errorMessageLoc;
}
if (result == S_FALSE) if (result == S_FALSE)
{ {
if (decryptionError && _items.IsEmpty()) if (decryptionError && _items.IsEmpty())
@@ -434,11 +452,11 @@ HRESULT CHandler::Open2(IInStream *stream,
_refItems.Add(refItem); _refItems.Add(refItem);
} }
_items.Add(item); _items.Add(item);
if (openArchiveCallback != NULL && _items.Size() % 100 == 0) if (openCallback && _items.Size() % 100 == 0)
{ {
UInt64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
UInt64 numBytes = curBytes + item.Position; UInt64 numBytes = curBytes + item.Position;
RINOK(openArchiveCallback->SetCompleted(&numFiles, &numBytes)); RINOK(openCallback->SetCompleted(&numFiles, &numBytes));
} }
} }
curBytes += endPos; curBytes += endPos;
@@ -450,13 +468,13 @@ HRESULT CHandler::Open2(IInStream *stream,
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *openCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
Close(); Close();
try try
{ {
HRESULT res = Open2(stream, maxCheckStartPosition, openArchiveCallback); HRESULT res = Open2(stream, maxCheckStartPosition, openCallback);
if (res != S_OK) if (res != S_OK)
Close(); Close();
return res; return res;

View File

@@ -4,11 +4,12 @@
#define __RAR_HANDLER_H #define __RAR_HANDLER_H
#include "../IArchive.h" #include "../IArchive.h"
#include "RarIn.h"
#include "RarVolumeInStream.h"
#include "../../Common/CreateCoder.h" #include "../../Common/CreateCoder.h"
#include "RarIn.h"
#include "RarVolumeInStream.h"
namespace NArchive { namespace NArchive {
namespace NRar { namespace NRar {
@@ -17,17 +18,6 @@ class CHandler:
PUBLIC_ISetCompressCodecsInfo PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp public CMyUnknownImp
{ {
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
QUERY_ENTRY_ISetCompressCodecsInfo
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
DECL_ISetCompressCodecsInfo
private:
CRecordVector<CRefItem> _refItems; CRecordVector<CRefItem> _refItems;
CObjectVector<CItemEx> _items; CObjectVector<CItemEx> _items;
CObjectVector<CInArchive> _archives; CObjectVector<CInArchive> _archives;
@@ -37,7 +27,6 @@ private:
DECL_EXTERNAL_CODECS_VARS DECL_EXTERNAL_CODECS_VARS
UInt64 GetPackSize(int refIndex) const; UInt64 GetPackSize(int refIndex) const;
// NArchive::NRar::CInArchive _archive;
bool IsSolid(int refIndex) bool IsSolid(int refIndex)
{ {
@@ -50,10 +39,26 @@ private:
} }
return item.IsSolid(); return item.IsSolid();
} }
void AddErrorMessage(const AString &s)
{
if (!_errorMessage.IsEmpty())
_errorMessage += '\n';
_errorMessage += s;
}
HRESULT Open2(IInStream *stream, HRESULT Open2(IInStream *stream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback); IArchiveOpenCallback *openCallback);
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
QUERY_ENTRY_ISetCompressCodecsInfo
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
DECL_ISetCompressCodecsInfo
}; };
}} }}

View File

@@ -5,9 +5,9 @@
#include "Common/Types.h" #include "Common/Types.h"
namespace NArchive{ namespace NArchive {
namespace NRar{ namespace NRar {
namespace NHeader{ namespace NHeader {
const int kMarkerSize = 7; const int kMarkerSize = 7;
extern Byte kMarker[kMarkerSize]; extern Byte kMarker[kMarkerSize];
@@ -46,29 +46,10 @@ namespace NArchive
const int kHeaderSizeMin = 7; const int kHeaderSizeMin = 7;
struct CBlock
{
UInt16 CRC;
Byte Type;
UInt16 Flags;
UInt16 Size;
UInt16 Reserved1;
UInt32 Reserved2;
// UInt16 GetRealCRC() const;
};
const int kArchiveHeaderSize = 13; const int kArchiveHeaderSize = 13;
const int kBlockHeadersAreEncrypted = 0x80; 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 namespace NFile

View File

@@ -3,6 +3,7 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../../C/7zCrc.h" #include "../../../../C/7zCrc.h"
#include "../../../../C/CpuArch.h"
#include "Common/StringConvert.h" #include "Common/StringConvert.h"
#include "Common/UTFConvert.h" #include "Common/UTFConvert.h"
@@ -14,9 +15,16 @@
#include "RarIn.h" #include "RarIn.h"
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
namespace NArchive { namespace NArchive {
namespace NRar { namespace NRar {
static const char *k_UnexpectedEnd = "Unexpected end of archive";
static const char *k_DecryptionError = "Decryption Error";
void CInArchive::ThrowExceptionWithCode( void CInArchive::ThrowExceptionWithCode(
CInArchiveException::CCauseType cause) CInArchiveException::CCauseType cause)
{ {
@@ -42,140 +50,80 @@ void CInArchive::Close()
m_Stream.Release(); m_Stream.Release();
} }
HRESULT CInArchive::ReadBytesSpec(void *data, size_t *resSize)
static inline bool TestMarkerCandidate(const void *aTestBytes)
{ {
for (UInt32 i = 0; i < NHeader::kMarkerSize; i++) if (m_CryptoMode)
if (((const Byte *)aTestBytes)[i] != NHeader::kMarker[i]) {
return false; size_t size = *resSize;
return true; *resSize = 0;
} const Byte *bufData = m_DecryptedDataAligned;
UInt32 bufSize = m_DecryptedDataSize;
HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) size_t i;
{ for (i = 0; i < size && m_CryptoPos < bufSize; i++)
RINOK(FindSignatureInStream(stream, ((Byte *)data)[i] = bufData[m_CryptoPos++];
NHeader::kMarker, NHeader::kMarkerSize, *resSize = i;
searchHeaderSizeLimit, m_ArchiveStartPosition)); return S_OK;
m_Stream = stream; }
m_Position = m_ArchiveStartPosition + NHeader::kMarkerSize; return ReadStream(m_Stream, data, resSize);
return m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL);
}
void CInArchive::ThrowUnexpectedEndOfArchiveException()
{
ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive);
} }
bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
{ {
if (m_CryptoMode) size_t processed = size;
{ if (ReadBytesSpec(data, &processed) != S_OK)
const Byte *bufData = m_DecryptedDataAligned; return false;
UInt32 bufSize = m_DecryptedDataSize; return processed == size;
UInt32 i;
for (i = 0; i < size && m_CryptoPos < bufSize; i++)
((Byte *)data)[i] = bufData[m_CryptoPos++];
return (i == size);
}
return (ReadStream_FALSE(m_Stream, data, size) == S_OK);
} }
void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size)
{
if(!ReadBytesAndTestSize(data,size))
ThrowUnexpectedEndOfArchiveException();
}
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
{
size_t realProcessedSize = size;
HRESULT result = ReadStream(m_Stream, data, &realProcessedSize);
if (processedSize != NULL)
*processedSize = (UInt32)realProcessedSize;
AddToSeekValue(realProcessedSize);
return result;
}
static UInt32 CrcUpdateUInt16(UInt32 crc, UInt16 v)
{
crc = CRC_UPDATE_BYTE(crc, (Byte)(v & 0xFF));
crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 8) & 0xFF));
return crc;
}
static UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 v)
{
crc = CRC_UPDATE_BYTE(crc, (Byte)(v & 0xFF));
crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 8) & 0xFF));
crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 16) & 0xFF));
crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 24) & 0xFF));
return crc;
}
HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{ {
m_CryptoMode = false; m_CryptoMode = false;
RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition)); RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition));
m_Position = m_StreamStartPosition; m_Position = m_StreamStartPosition;
RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); UInt64 arcStartPos;
RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
searchHeaderSizeLimit, arcStartPos));
m_Position = arcStartPos + NHeader::kMarkerSize;
RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL));
Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1];
Byte buf[NHeader::NArchive::kArchiveHeaderSize]; RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize));
UInt32 processedSize; AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize);
ReadBytes(buf, sizeof(buf), &processedSize);
if (processedSize != sizeof(buf))
return S_FALSE;
m_CurData = buf;
m_CurPos = 0;
m_PosLimit = sizeof(buf);
m_ArchiveHeader.CRC = ReadUInt16();
m_ArchiveHeader.Type = ReadByte();
m_ArchiveHeader.Flags = ReadUInt16();
m_ArchiveHeader.Size = ReadUInt16();
m_ArchiveHeader.Reserved1 = ReadUInt16();
m_ArchiveHeader.Reserved2 = ReadUInt32();
m_ArchiveHeader.EncryptVersion = 0;
UInt32 crc = CRC_INIT_VAL; UInt32 blockSize = Get16(buf + 5);
crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.Type);
crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Flags);
crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Size);
crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Reserved1);
crc = CrcUpdateUInt32(crc, m_ArchiveHeader.Reserved2);
if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) _header.EncryptVersion = 0;
_header.Flags = Get16(buf + 3);
UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize;
if (_header.IsThereEncryptVer())
{ {
ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); if (blockSize <= headerSize)
if (processedSize != 1)
return S_FALSE; return S_FALSE;
crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion); RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1));
AddToSeekValue(1);
_header.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize];
headerSize += 1;
} }
if (blockSize < headerSize ||
if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF)) buf[2] != NHeader::NBlockType::kArchiveHeader ||
ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); (UInt32)Get16(buf) != (CrcCalc(buf + 2, headerSize - 2) & 0xFFFF))
if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader)
return S_FALSE; return S_FALSE;
m_ArchiveCommentPosition = m_Position;
m_SeekOnArchiveComment = true;
return S_OK;
}
void CInArchive::SkipArchiveComment() size_t commentSize = blockSize - headerSize;
{ _comment.SetCapacity(commentSize);
if (!m_SeekOnArchiveComment) RINOK(ReadStream_FALSE(stream, _comment, commentSize));
return; AddToSeekValue(commentSize);
AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize()); m_Stream = stream;
m_SeekOnArchiveComment = false; _header.StartPosition = arcStartPos;
return S_OK;
} }
void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
{ {
archiveInfo.StartPosition = m_ArchiveStartPosition; archiveInfo = _header;
archiveInfo.Flags = m_ArchiveHeader.Flags;
archiveInfo.CommentPosition = m_ArchiveCommentPosition;
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,
@@ -375,26 +323,21 @@ void CInArchive::AddToSeekValue(UInt64 addValue)
HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage) HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage)
{ {
decryptionError = false; decryptionError = false;
if (m_SeekOnArchiveComment)
SkipArchiveComment();
for (;;) for (;;)
{ {
if (!SeekInArchive(m_Position)) SeekInArchive(m_Position);
return S_FALSE; if (!m_CryptoMode && (_header.Flags &
if (!m_CryptoMode && (m_ArchiveHeader.Flags &
NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
{ {
m_CryptoMode = false; m_CryptoMode = false;
if (getTextPassword == 0) if (getTextPassword == 0)
return S_FALSE; return S_FALSE;
if(!SeekInArchive(m_Position))
return S_FALSE;
if (!m_RarAES) if (!m_RarAES)
{ {
m_RarAESSpec = new NCrypto::NRar29::CDecoder; m_RarAESSpec = new NCrypto::NRar29::CDecoder;
m_RarAES = m_RarAESSpec; m_RarAES = m_RarAESSpec;
} }
m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld()); m_RarAESSpec->SetRar350Mode(_header.IsEncryptOld());
// Salt // Salt
const UInt32 kSaltSize = 8; const UInt32 kSaltSize = 8;
@@ -438,9 +381,12 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
} }
m_FileHeaderData.EnsureCapacity(7); m_FileHeaderData.EnsureCapacity(7);
if (!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7)) size_t processed = 7;
RINOK(ReadBytesSpec((Byte *)m_FileHeaderData, &processed));
if (processed != 7)
{ {
errorMessage = "Unexpected end of archive"; if (processed != 0)
errorMessage = k_UnexpectedEnd;
return S_FALSE; return S_FALSE;
} }
@@ -463,7 +409,12 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize); m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize);
m_CurData = (Byte *)m_FileHeaderData; m_CurData = (Byte *)m_FileHeaderData;
m_PosLimit = m_BlockHeader.HeadSize; m_PosLimit = m_BlockHeader.HeadSize;
ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7); if (!ReadBytesAndTestSize(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7))
{
errorMessage = k_UnexpectedEnd;
return S_FALSE;
}
ReadHeaderReal(item); ReadHeaderReal(item);
if ((CrcCalc(m_CurData + 2, if ((CrcCalc(m_CurData + 2,
m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC) m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC)
@@ -478,19 +429,25 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10))
{ {
decryptionError = true; decryptionError = true;
errorMessage = k_DecryptionError;
return S_FALSE; return S_FALSE;
} }
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
{ {
m_FileHeaderData.EnsureCapacity(7 + 4); m_FileHeaderData.EnsureCapacity(7 + 4);
m_CurData = (Byte *)m_FileHeaderData; m_CurData = (Byte *)m_FileHeaderData;
ReadBytesAndTestResult(m_CurData + m_CurPos, 4); // test it if (!ReadBytesAndTestSize(m_CurData + m_CurPos, 4))
{
errorMessage = k_UnexpectedEnd;
return S_FALSE;
}
m_PosLimit = 7 + 4; m_PosLimit = 7 + 4;
UInt32 dataSize = ReadUInt32(); UInt32 dataSize = ReadUInt32();
AddToSeekValue(dataSize); AddToSeekValue(dataSize);
if (m_CryptoMode && dataSize > (1 << 27)) if (m_CryptoMode && dataSize > (1 << 27))
{ {
decryptionError = true; decryptionError = true;
errorMessage = k_DecryptionError;
return S_FALSE; return S_FALSE;
} }
m_CryptoPos = m_BlockHeader.HeadSize; m_CryptoPos = m_BlockHeader.HeadSize;
@@ -503,11 +460,9 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
} }
} }
bool CInArchive::SeekInArchive(UInt64 position) void CInArchive::SeekInArchive(UInt64 position)
{ {
UInt64 newPosition; m_Stream->Seek(position, STREAM_SEEK_SET, NULL);
m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition);
return newPosition == position;
} }
ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size)

View File

@@ -33,18 +33,20 @@ public:
CInArchiveException(CCauseType cause) : Cause(cause) {} CInArchiveException(CCauseType cause) : Cause(cause) {}
}; };
class CInArchiveInfo
struct CInArchiveInfo
{ {
public: UInt32 Flags;
Byte EncryptVersion;
UInt64 StartPosition; UInt64 StartPosition;
UInt16 Flags;
UInt64 CommentPosition;
UInt16 CommentSize;
bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; }
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }
bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; }
bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } 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); }
}; };
class CInArchive class CInArchive
@@ -52,23 +54,19 @@ class CInArchive
CMyComPtr<IInStream> m_Stream; CMyComPtr<IInStream> m_Stream;
UInt64 m_StreamStartPosition; UInt64 m_StreamStartPosition;
UInt64 m_Position;
UInt64 m_ArchiveStartPosition;
NHeader::NArchive::CHeader360 m_ArchiveHeader; CInArchiveInfo _header;
CDynamicBuffer<char> m_NameBuffer; CDynamicBuffer<char> m_NameBuffer;
CDynamicBuffer<wchar_t> _unicodeNameBuffer; CDynamicBuffer<wchar_t> _unicodeNameBuffer;
bool m_SeekOnArchiveComment;
UInt64 m_ArchiveCommentPosition; CByteBuffer _comment;
void ReadName(CItemEx &item, int nameSize); void ReadName(CItemEx &item, int nameSize);
void ReadHeaderReal(CItemEx &item); void ReadHeaderReal(CItemEx &item);
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *aProcessedSize); HRESULT ReadBytesSpec(void *data, size_t *size);
bool ReadBytesAndTestSize(void *data, UInt32 size); bool ReadBytesAndTestSize(void *data, UInt32 size);
void ReadBytesAndTestResult(void *data, UInt32 size);
HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit); HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
void ThrowExceptionWithCode(CInArchiveException::CCauseType cause); void ThrowExceptionWithCode(CInArchiveException::CCauseType cause);
@@ -108,15 +106,15 @@ class CInArchive
} }
public: public:
UInt64 m_Position;
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
void Close(); void Close();
HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage); HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage);
void SkipArchiveComment();
void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
bool SeekInArchive(UInt64 position); void SeekInArchive(UInt64 position);
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
}; };

View File

@@ -1,8 +1,8 @@
#define MY_VER_MAJOR 9 #define MY_VER_MAJOR 9
#define MY_VER_MINOR 18 #define MY_VER_MINOR 19
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION "9.18 beta" #define MY_VERSION "9.19 beta"
#define MY_7ZIP_VERSION "7-Zip 9.18 beta" #define MY_7ZIP_VERSION "7-Zip 9.19 beta"
#define MY_DATE "2010-11-02" #define MY_DATE "2010-11-11"
#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov" #define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE

View File

@@ -187,6 +187,7 @@ static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfil
static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
static const char *kTerminalOutError = "I won't write compressed data to a terminal"; static const char *kTerminalOutError = "I won't write compressed data to a terminal";
static const char *kSameTerminalError = "I won't write data and program's messages to same terminal"; static const char *kSameTerminalError = "I won't write data and program's messages to same terminal";
static const char *kEmptyFilePath = "Empty file path";
static void ThrowException(const char *errorMessage) static void ThrowException(const char *errorMessage)
{ {
@@ -301,6 +302,8 @@ static void AddToCensorFromNonSwitchesStrings(
for (int i = startIndex; i < nonSwitchStrings.Size(); i++) for (int i = startIndex; i < nonSwitchStrings.Size(); i++)
{ {
const UString &s = nonSwitchStrings[i]; const UString &s = nonSwitchStrings[i];
if (s.IsEmpty())
throw kEmptyFilePath;
if (s[0] == kFileListID) if (s[0] == kFileListID)
AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage); AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
else else
@@ -861,6 +864,8 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (curCommandIndex >= numNonSwitchStrings) if (curCommandIndex >= numNonSwitchStrings)
ThrowUserErrorException(); ThrowUserErrorException();
options.ArchiveName = nonSwitchStrings[curCommandIndex++]; options.ArchiveName = nonSwitchStrings[curCommandIndex++];
if (options.ArchiveName.IsEmpty())
ThrowUserErrorException();
} }
AddToCensorFromNonSwitchesStrings( AddToCensorFromNonSwitchesStrings(

View File

@@ -387,12 +387,11 @@ static HRESULT Compress(
CMyComPtr<ISequentialOutStream> outStream; CMyComPtr<ISequentialOutStream> outStream;
const UString &archiveName = archivePath.GetFinalPath();
if (!stdOutMode) if (!stdOutMode)
{ {
UString resultPath; UString resultPath;
int pos; int pos;
if (!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) if (!NFile::NDirectory::MyGetFullPathName(archivePath.GetFinalPath(), resultPath, pos))
throw 1417161; throw 1417161;
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
} }
@@ -676,35 +675,38 @@ HRESULT UpdateArchive(
} }
} }
const UString archiveName = options.ArchivePath.GetFinalPath();
CArchiveLink archiveLink; CArchiveLink arcLink;
NFind::CFileInfoW archiveFileInfo; const UString arcPath = options.ArchivePath.GetFinalPath();
if (archiveFileInfo.Find(archiveName)) if (!options.ArchivePath.OriginalPath.IsEmpty())
{ {
if (archiveFileInfo.IsDir()) NFind::CFileInfoW fi;
throw "there is no such archive"; if (fi.Find(arcPath))
if (options.VolumesSizes.Size() > 0)
return E_NOTIMPL;
CIntVector formatIndices;
if (options.MethodMode.FormatIndex >= 0)
formatIndices.Add(options.MethodMode.FormatIndex);
HRESULT result = archiveLink.Open2(codecs, formatIndices, false, NULL, archiveName, openCallback);
if (result == E_ABORT)
return result;
RINOK(callback->OpenResult(archiveName, result));
RINOK(result);
if (archiveLink.VolumePaths.Size() > 1)
{ {
errorInfo.SystemError = (DWORD)E_NOTIMPL; if (fi.IsDir())
errorInfo.Message = L"Updating for multivolume archives is not implemented"; throw "there is no such archive";
return E_NOTIMPL; if (options.VolumesSizes.Size() > 0)
} return E_NOTIMPL;
CIntVector formatIndices;
if (options.MethodMode.FormatIndex >= 0)
formatIndices.Add(options.MethodMode.FormatIndex);
HRESULT result = arcLink.Open2(codecs, formatIndices, false, NULL, arcPath, openCallback);
if (result == E_ABORT)
return result;
RINOK(callback->OpenResult(arcPath, result));
RINOK(result);
if (arcLink.VolumePaths.Size() > 1)
{
errorInfo.SystemError = (DWORD)E_NOTIMPL;
errorInfo.Message = L"Updating for multivolume archives is not implemented";
return E_NOTIMPL;
}
CArc &arc = archiveLink.Arcs.Back(); CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = !archiveFileInfo.IsDevice; arc.MTimeDefined = !fi.IsDevice;
arc.MTime = archiveFileInfo.MTime; arc.MTime = fi.MTime;
}
} }
else else
{ {
@@ -771,7 +773,7 @@ HRESULT UpdateArchive(
bool createTempFile = false; bool createTempFile = false;
bool thereIsInArchive = archiveLink.IsOpen; bool thereIsInArchive = arcLink.IsOpen;
if (!options.StdOutMode && options.UpdateArchiveItself) if (!options.StdOutMode && options.UpdateArchiveItself)
{ {
@@ -800,7 +802,8 @@ HRESULT UpdateArchive(
// ap.Temp = true; // ap.Temp = true;
// ap.TempPrefix = tempDirPrefix; // ap.TempPrefix = tempDirPrefix;
} }
if (i > 0 || !createTempFile) if (!options.StdOutMode &&
(i > 0 || !createTempFile))
{ {
const UString &path = ap.GetFinalPath(); const UString &path = ap.GetFinalPath();
if (NFind::DoesFileOrDirExist(path)) if (NFind::DoesFileOrDirExist(path))
@@ -816,18 +819,18 @@ HRESULT UpdateArchive(
CObjectVector<CArcItem> arcItems; CObjectVector<CArcItem> arcItems;
if (thereIsInArchive) if (thereIsInArchive)
{ {
RINOK(EnumerateInArchiveItems(censor, archiveLink.Arcs.Back(), arcItems)); RINOK(EnumerateInArchiveItems(censor, arcLink.Arcs.Back(), arcItems));
} }
RINOK(UpdateWithItemLists(codecs, options, RINOK(UpdateWithItemLists(codecs, options,
thereIsInArchive ? archiveLink.GetArchive() : 0, thereIsInArchive ? arcLink.GetArchive() : 0,
arcItems, dirItems, arcItems, dirItems,
tempFiles, errorInfo, callback)); tempFiles, errorInfo, callback));
if (thereIsInArchive) if (thereIsInArchive)
{ {
RINOK(archiveLink.Close()); RINOK(arcLink.Close());
archiveLink.Release(); arcLink.Release();
} }
tempFiles.Paths.Clear(); tempFiles.Paths.Clear();
@@ -838,19 +841,19 @@ HRESULT UpdateArchive(
CArchivePath &ap = options.Commands[0].ArchivePath; CArchivePath &ap = options.Commands[0].ArchivePath;
const UString &tempPath = ap.GetTempPath(); const UString &tempPath = ap.GetTempPath();
if (thereIsInArchive) if (thereIsInArchive)
if (!NDirectory::DeleteFileAlways(archiveName)) if (!NDirectory::DeleteFileAlways(arcPath))
{ {
errorInfo.SystemError = ::GetLastError(); errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot delete the file"; errorInfo.Message = L"7-Zip cannot delete the file";
errorInfo.FileName = archiveName; errorInfo.FileName = arcPath;
return E_FAIL; return E_FAIL;
} }
if (!NDirectory::MyMoveFile(tempPath, archiveName)) if (!NDirectory::MyMoveFile(tempPath, arcPath))
{ {
errorInfo.SystemError = ::GetLastError(); errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot move the file"; errorInfo.Message = L"7-Zip cannot move the file";
errorInfo.FileName = tempPath; errorInfo.FileName = tempPath;
errorInfo.FileName2 = archiveName; errorInfo.FileName2 = arcPath;
return E_FAIL; return E_FAIL;
} }
} }

View File

@@ -1,20 +1,20 @@
// Update.h // Update.h
#ifndef __UPDATE_H #ifndef __COMMON_UPDATE_H
#define __UPDATE_H #define __COMMON_UPDATE_H
#include "Common/Wildcard.h" #include "Common/Wildcard.h"
#include "Windows/FileFind.h"
#include "../../Archive/IArchive.h"
#include "UpdateAction.h"
#include "ArchiveOpenCallback.h" #include "ArchiveOpenCallback.h"
#include "UpdateCallback.h"
#include "Property.h"
#include "LoadCodecs.h" #include "LoadCodecs.h"
#include "Property.h"
#include "UpdateAction.h"
#include "UpdateCallback.h"
struct CArchivePath struct CArchivePath
{ {
UString OriginalPath;
UString Prefix; // path(folder) prefix including slash UString Prefix; // path(folder) prefix including slash
UString Name; // base name UString Name; // base name
UString BaseExtension; // archive type extension or "exe" extension UString BaseExtension; // archive type extension or "exe" extension
@@ -28,11 +28,11 @@ struct CArchivePath
void ParseFromPath(const UString &path) void ParseFromPath(const UString &path)
{ {
OriginalPath = path;
SplitPathToParts(path, Prefix, Name); SplitPathToParts(path, Prefix, Name);
if (Name.IsEmpty())
return;
int dotPos = Name.ReverseFind(L'.'); int dotPos = Name.ReverseFind(L'.');
if (dotPos <= 0) if (dotPos < 0)
return; return;
if (dotPos == Name.Length() - 1) if (dotPos == Name.Length() - 1)
{ {

View File

@@ -53,9 +53,33 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
} }
} }
#ifdef _WIN32
#ifndef UNDER_CE
#define MY_DISABLE_ECHO
#endif
#endif
UString GetPassword(CStdOutStream *outStream) UString GetPassword(CStdOutStream *outStream)
{ {
(*outStream) << "\nEnter password:"; (*outStream) << "\nEnter password"
#ifdef MY_DISABLE_ECHO
" (will not be echoed)"
#endif
":";
outStream->Flush(); outStream->Flush();
#ifdef MY_DISABLE_ECHO
HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
bool wasChanged = false;
DWORD mode = 0;
if (console != INVALID_HANDLE_VALUE && console != 0)
if (GetConsoleMode(console, &mode))
wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0);
UString res = g_StdIn.ScanUStringUntilNewLine();
if (wasChanged)
SetConsoleMode(console, mode);
return res;
#else
return g_StdIn.ScanUStringUntilNewLine(); return g_StdIn.ScanUStringUntilNewLine();
#endif
} }

View File

@@ -125,6 +125,8 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
} }
case 'A': case 'A':
{ {
// probably that code is unused ?
/*
bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
if (ctrl) if (ctrl)
{ {
@@ -133,6 +135,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
_listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); _listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
return true; return true;
} }
*/
} }
} }
} }

View File

@@ -210,7 +210,7 @@ static const char *kStartExtensions =
#endif #endif
" exe bat com" " exe bat com"
" chm" " chm"
" msi doc xls ppt pps wps wpt wks xlr wdb vsd" " msi doc xls ppt pps wps wpt wks xlr wdb vsd pub"
" docx docm dotx dotm xlsx xlsm xltx xltm xlsb" " docx docm dotx dotm xlsx xlsm xltx xltm xlsb"
" xlam pptx pptm potx potm ppam ppsx ppsm xsn" " xlam pptx pptm potx potm ppam ppsx ppsm xsn"

View File

@@ -439,6 +439,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
{ {
if (focusedPos >= _listView.GetItemCount()) if (focusedPos >= _listView.GetItemCount())
focusedPos = _listView.GetItemCount() - 1; focusedPos = _listView.GetItemCount() - 1;
// we select item only in showDots mode.
SetFocusedSelectedItem(focusedPos, showDots); SetFocusedSelectedItem(focusedPos, showDots);
} }
// m_RedrawEnabled = true; // m_RedrawEnabled = true;
@@ -484,7 +485,7 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UInt32> &indices) const
{ {
int realIndex = GetRealItemIndex(focusedItem); int realIndex = GetRealItemIndex(focusedItem);
if (realIndex != kParentIndex) if (realIndex != kParentIndex)
indices.Add(realIndex); indices.Add(realIndex);
} }
} }
} }

View File

@@ -245,7 +245,14 @@ void CPanel::KillSelection()
{ {
int focused = _listView.GetFocusedItem(); int focused = _listView.GetFocusedItem();
if (focused >= 0) if (focused >= 0)
{
// CPanel::OnItemChanged notify for LVIS_SELECTED change doesn't work here. Why?
// so we change _selectedStatusVector[realIndex] here.
int realIndex = GetRealItemIndex(focused);
if (realIndex != kParentIndex)
_selectedStatusVector[realIndex] = true;
_listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED); _listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED);
}
} }
} }
@@ -297,4 +304,3 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
} }
return; return;
} }

View File

@@ -6,7 +6,7 @@
namespace NCommandLineParser { namespace NCommandLineParser {
void SplitCommandLine(const UString &src, UString &dest1, UString &dest2) bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
{ {
dest1.Empty(); dest1.Empty();
dest2.Empty(); dest2.Empty();
@@ -15,17 +15,17 @@ void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
for (i = 0; i < src.Length(); i++) for (i = 0; i < src.Length(); i++)
{ {
wchar_t c = src[i]; wchar_t c = src[i];
if (c == L' ' && !quoteMode)
{
dest2 = src.Mid(i + 1);
return i != 0;
}
if (c == L'\"') if (c == L'\"')
quoteMode = !quoteMode; quoteMode = !quoteMode;
else if (c == L' ' && !quoteMode)
{
i++;
break;
}
else else
dest1 += c; dest1 += c;
} }
dest2 = src.Mid(i); return i != 0;
} }
void SplitCommandLine(const UString &s, UStringVector &parts) void SplitCommandLine(const UString &s, UStringVector &parts)
@@ -36,10 +36,7 @@ void SplitCommandLine(const UString &s, UStringVector &parts)
for (;;) for (;;)
{ {
UString s1, s2; UString s1, s2;
SplitCommandLine(sTemp, s1, s2); if (SplitCommandLine(sTemp, s1, s2))
// s1.Trim();
// s2.Trim();
if (!s1.IsEmpty())
parts.Add(s1); parts.Add(s1);
if (s2.IsEmpty()) if (s2.IsEmpty())
break; break;

View File

@@ -1,13 +1,13 @@
// Common/CommandLineParser.h // Common/CommandLineParser.h
#ifndef __COMMON_COMMANDLINEPARSER_H #ifndef __COMMON_COMMAND_LINE_PARSER_H
#define __COMMON_COMMANDLINEPARSER_H #define __COMMON_COMMAND_LINE_PARSER_H
#include "MyString.h" #include "MyString.h"
namespace NCommandLineParser { namespace NCommandLineParser {
void SplitCommandLine(const UString &src, UString &dest1, UString &dest2); bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
void SplitCommandLine(const UString &s, UStringVector &parts); void SplitCommandLine(const UString &s, UStringVector &parts);
namespace NSwitchType { namespace NSwitchType {

View File

@@ -374,6 +374,8 @@ int CCensor::FindPrefix(const UString &prefix) const
void CCensor::AddItem(bool include, const UString &path, bool recursive) void CCensor::AddItem(bool include, const UString &path, bool recursive)
{ {
UStringVector pathParts; UStringVector pathParts;
if (path.IsEmpty())
throw "Empty file path";
SplitPathToParts(path, pathParts); SplitPathToParts(path, pathParts);
bool forFile = true; bool forFile = true;
if (pathParts.Back().IsEmpty()) if (pathParts.Back().IsEmpty())

View File

@@ -474,7 +474,7 @@ bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartS
{ {
resultPath = fileName; resultPath = fileName;
// change it // change it
fileNamePartStartIndex = resultPath.ReverseFind('\\'); fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);
fileNamePartStartIndex++; fileNamePartStartIndex++;
return true; return true;
} }
@@ -488,6 +488,38 @@ bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
return (needLength > 0 && needLength < MAX_PATH); return (needLength > 0 && needLength < MAX_PATH);
} }
#ifdef WIN_LONG_PATH
static UString GetLastPart(LPCWSTR path)
{
int i = (int)wcslen(path);
for (; i > 0; i--)
{
WCHAR c = path[i - 1];
if (c == WCHAR_PATH_SEPARATOR || c == '/')
break;
}
return path + i;
}
static void AddTrailingDots(LPCWSTR oldPath, UString &newPath)
{
int len = (int)wcslen(oldPath);
int i;
for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
if (i == 0 || i == len)
return;
UString oldName = GetLastPart(oldPath);
UString newName = GetLastPart(newPath);
int nonDotsLen = oldName.Length() - (len - i);
if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
return;
for (; i != len; i++)
newPath += '.';
}
#endif
bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex) bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
{ {
resultPath.Empty(); resultPath.Empty();
@@ -512,6 +544,11 @@ bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePa
fileNamePartStartIndex = lstrlen(fileName); fileNamePartStartIndex = lstrlen(fileName);
else else
fileNamePartStartIndex = (int)(fileNamePointer - buffer); fileNamePartStartIndex = (int)(fileNamePointer - buffer);
#ifdef _UNICODE
#ifdef WIN_LONG_PATH
AddTrailingDots(fileName, resultPath);
#endif
#endif
return true; return true;
} }
@@ -542,6 +579,9 @@ bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartS
fileNamePartStartIndex = MyStringLen(fileName); fileNamePartStartIndex = MyStringLen(fileName);
else else
fileNamePartStartIndex = (int)(fileNamePointer - buffer); fileNamePartStartIndex = (int)(fileNamePointer - buffer);
#ifdef WIN_LONG_PATH
AddTrailingDots(fileName, resultPath);
#endif
} }
else else
{ {

View File

@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName% InstallDir = %CE1%\%AppName%
[Strings] [Strings]
AppVer = "9.18" AppVer = "9.19"
AppDate = "2010-11-02" AppDate = "2010-11-11"
[CEDevice] [CEDevice]
; ProcessorType = 2577 ; ARM ; ProcessorType = 2577 ; ARM

View File

@@ -2,7 +2,7 @@
;Defines ;Defines
!define VERSION_MAJOR 9 !define VERSION_MAJOR 9
!define VERSION_MINOR 18 !define VERSION_MINOR 19
!define VERSION_POSTFIX_FULL " beta" !define VERSION_POSTFIX_FULL " beta"
!ifdef WIN64 !ifdef WIN64
!ifdef IA64 !ifdef IA64

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<?define VerMajor = "9" ?> <?define VerMajor = "9" ?>
<?define VerMinor = "18" ?> <?define VerMinor = "19" ?>
<?define VerBuild = "00" ?> <?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?> <?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "0$(var.VerMajor)$(var.VerMinor)" ?> <?define MmHex = "0$(var.VerMajor)$(var.VerMinor)" ?>

View File

@@ -1,4 +1,4 @@
LZMA SDK 9.18 LZMA SDK 9.19
------------- -------------
LZMA SDK provides the documentation, samples, header files, libraries, LZMA SDK provides the documentation, samples, header files, libraries,

View File

@@ -1,4 +1,4 @@
7-Zip 9.18 Sources 7-Zip 9.19 Sources
------------------ ------------------
7-Zip is a file archiver for Windows. 7-Zip is a file archiver for Windows.