This commit is contained in:
Igor Pavlov
2018-05-02 22:28:04 +01:00
committed by Kornel
parent f19b649c73
commit 18dc2b4161
121 changed files with 3523 additions and 1866 deletions

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 18 #define MY_VER_MAJOR 18
#define MY_VER_MINOR 03 #define MY_VER_MINOR 05
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "18.03 beta" #define MY_VERSION_NUMBERS "18.05"
#define MY_VERSION MY_VERSION_NUMBERS #define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME #ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION #define MY_VERSION_CPU MY_VERSION
#endif #endif
#define MY_DATE "2018-03-04" #define MY_DATE "2018-04-30"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"

View File

@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions /* Alloc.c -- Memory allocation functions
2018-03-01 : Igor Pavlov : Public domain */ 2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -283,7 +283,7 @@ const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align) #define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
#if (_POSIX_C_SOURCE >= 200112L) #if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
#define USE_posix_memalign #define USE_posix_memalign
#endif #endif

View File

@@ -1,5 +1,5 @@
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2017-04-03 : Igor Pavlov : Public domain */ 2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -232,10 +232,10 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
if (rem < 4) if (rem < 4)
{ {
SizeT i; p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
SetUi32(p->temp, val); p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
for (i = 0; i < rem; i++) p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
dest[i] = p->temp[i]; p->temp[3] = (Byte)val;
p->dest = dest + rem; p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break; break;

View File

@@ -1,5 +1,5 @@
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code) /* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -12,7 +12,6 @@
#define PRF(x) #define PRF(x)
#endif #endif
#include <windows.h>
#include <string.h> #include <string.h>
#include "Bcj2.h" #include "Bcj2.h"

View File

@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder /* Lzma2Enc.c -- LZMA2 Encoder
2018-02-08 : Igor Pavlov : Public domain */ 2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -369,7 +369,9 @@ typedef struct
ISeqOutStream *outStream; ISeqOutStream *outStream;
Byte *outBuf; Byte *outBuf;
size_t outBufSize; size_t outBuf_Rem; /* remainder in outBuf */
size_t outBufSize; /* size of allocated outBufs[i] */
size_t outBufsDataSizes[MTCODER__BLOCKS_MAX]; size_t outBufsDataSizes[MTCODER__BLOCKS_MAX];
Bool mtCoder_WasConstructed; Bool mtCoder_WasConstructed;
CMtCoder mtCoder; CMtCoder mtCoder;
@@ -699,10 +701,10 @@ static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex)
if (me->outStream) if (me->outStream)
return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE; return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE;
if (size > me->outBufSize) if (size > me->outBuf_Rem)
return SZ_ERROR_OUTPUT_EOF; return SZ_ERROR_OUTPUT_EOF;
memcpy(me->outBuf, data, size); memcpy(me->outBuf, data, size);
me->outBufSize -= size; me->outBuf_Rem -= size;
me->outBuf += size; me->outBuf += size;
return SZ_OK; return SZ_OK;
} }
@@ -749,11 +751,11 @@ SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
p->outStream = outStream; p->outStream = outStream;
p->outBuf = NULL; p->outBuf = NULL;
p->outBufSize = 0; p->outBuf_Rem = 0;
if (!outStream) if (!outStream)
{ {
p->outBuf = outBuf; p->outBuf = outBuf;
p->outBufSize = *outBufSize; p->outBuf_Rem = *outBufSize;
*outBufSize = 0; *outBufSize = 0;
} }

View File

@@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2018-02-06 : Igor Pavlov : Public domain */ 2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H #ifndef __LZMA_DEC_H
#define __LZMA_DEC_H #define __LZMA_DEC_H
@@ -12,11 +12,13 @@ EXTERN_C_BEGIN
/* _LZMA_PROB32 can increase the speed on some CPUs, /* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */ but memory usage for CLzmaDec::probs will be doubled in that case */
typedef
#ifdef _LZMA_PROB32 #ifdef _LZMA_PROB32
#define CLzmaProb UInt32 UInt32
#else #else
#define CLzmaProb UInt16 UInt16
#endif #endif
CLzmaProb;
/* ---------- LZMA Properties ---------- */ /* ---------- LZMA Properties ---------- */
@@ -76,8 +78,8 @@ typedef struct
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams: /* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum typedef enum
{ {
@@ -147,7 +149,7 @@ void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
You must work with CLzmaDec variables directly in this interface. You must work with CLzmaDec variables directly in this interface.
STEPS: STEPS:
LzmaDec_Constr() LzmaDec_Construct()
LzmaDec_Allocate() LzmaDec_Allocate()
for (each new stream) for (each new stream)
{ {

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder /* 7zMain.c - Test application for 7z Decoder
2017-08-26 : Igor Pavlov : Public domain */ 2018-04-19 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -607,6 +607,31 @@ int MY_CDECL main(int numargs, char *args[])
break; break;
} }
#ifdef USE_WINDOWS_FILE
{
FILETIME mtime, ctime;
FILETIME *mtimePtr = NULL;
FILETIME *ctimePtr = NULL;
if (SzBitWithVals_Check(&db.MTime, i))
{
const CNtfsFileTime *t = &db.MTime.Vals[i];
mtime.dwLowDateTime = (DWORD)(t->Low);
mtime.dwHighDateTime = (DWORD)(t->High);
mtimePtr = &mtime;
}
if (SzBitWithVals_Check(&db.CTime, i))
{
const CNtfsFileTime *t = &db.CTime.Vals[i];
ctime.dwLowDateTime = (DWORD)(t->Low);
ctime.dwHighDateTime = (DWORD)(t->High);
ctimePtr = &ctime;
}
if (mtimePtr || ctimePtr)
SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr);
}
#endif
if (File_Close(&outFile)) if (File_Close(&outFile))
{ {
PrintError("can not close output file"); PrintError("can not close output file");

View File

@@ -1,4 +1,5 @@
PROG = 7zipInstall.exe PROG = 7zipInstall.exe
MY_FIXED = 1
LIBS = $(LIBS) version.lib LIBS = $(LIBS) version.lib

View File

@@ -1,4 +1,5 @@
PROG = 7zipUninstall.exe PROG = 7zipUninstall.exe
MY_FIXED = 1
!IFDEF _64BIT_INSTALLER !IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER

View File

@@ -1,4 +1,5 @@
PROG = 7zS2.sfx PROG = 7zS2.sfx
MY_FIXED = 1
C_OBJS = \ C_OBJS = \
$O\7zAlloc.obj \ $O\7zAlloc.obj \

View File

@@ -1,4 +1,5 @@
PROG = 7zS2con.sfx PROG = 7zS2con.sfx
MY_FIXED = 1
CFLAGS = $(CFLAGS) -D_CONSOLE CFLAGS = $(CFLAGS) -D_CONSOLE
C_OBJS = \ C_OBJS = \

View File

@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode /* XzDec.c -- Xz Decode
2018-02-28 : Igor Pavlov : Public domain */ 2018-04-24 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -2673,7 +2673,7 @@ SRes XzDecMt_Decode(CXzDecMtHandle pp,
if (p->finishedDecoderIndex >= 0) if (p->finishedDecoderIndex >= 0)
{ {
CXzDecMtThread *coder = &p->coders[p->finishedDecoderIndex]; CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex];
codeRes = coder->codeRes; codeRes = coder->codeRes;
dec = &coder->dec; dec = &coder->dec;
status = coder->status; status = coder->status;

View File

@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode /* XzEnc.c -- Xz Encode
2018-02-21 : Igor Pavlov : Public domain */ 2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -1255,6 +1255,8 @@ SRes XzEnc_Encode(CXzEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStr
rem = props->reduceSize - progress2.inOffset; rem = props->reduceSize - progress2.inOffset;
*/ */
blockSizes.headerSize = 0; // for GCC
RINOK(Xz_CompressBlock( RINOK(Xz_CompressBlock(
&p->lzmaf_Items[0], &p->lzmaf_Items[0],

View File

@@ -549,9 +549,9 @@ private:
Byte *TempBuf; Byte *TempBuf;
UInt32 TempBufSize; UInt32 TempBufSize;
UInt32 TempBufWritten;
unsigned NumIdenticalFiles; unsigned NumIdenticalFiles;
bool TempBufMode; bool TempBufMode;
UInt32 m_BufStartFolderOffset;
unsigned m_StartIndex; unsigned m_StartIndex;
unsigned m_CurrentIndex; unsigned m_CurrentIndex;
@@ -575,7 +575,6 @@ private:
HRESULT OpenFile(); HRESULT OpenFile();
HRESULT CloseFileWithResOp(Int32 resOp); HRESULT CloseFileWithResOp(Int32 resOp);
HRESULT CloseFile(); HRESULT CloseFile();
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
public: public:
HRESULT WriteEmptyFiles(); HRESULT WriteEmptyFiles();
@@ -672,11 +671,11 @@ HRESULT CFolderOutStream::OpenFile()
FreeTempBuf(); FreeTempBuf();
TempBuf = (Byte *)MyAlloc(item.Size); TempBuf = (Byte *)MyAlloc(item.Size);
TempBufSize = item.Size; TempBufSize = item.Size;
if (TempBuf == NULL) if (!TempBuf)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
TempBufMode = true; TempBufMode = true;
m_BufStartFolderOffset = item.Offset; TempBufWritten = 0;
} }
else if (numExtractItems == 1) else if (numExtractItems == 1)
{ {
@@ -725,8 +724,9 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
} }
HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) HRESULT CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{ {
// (data == NULL) means Error_Data for solid folder flushing
COM_TRY_BEGIN COM_TRY_BEGIN
UInt32 realProcessed = 0; UInt32 realProcessed = 0;
@@ -741,20 +741,33 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
HRESULT res = S_OK; HRESULT res = S_OK;
if (numBytesToWrite != 0) if (numBytesToWrite != 0)
{ {
if (!isOK) if (!data)
m_IsOk = false; m_IsOk = false;
if (m_RealOutStream) if (m_RealOutStream)
{ {
UInt32 processedSizeLocal = 0; UInt32 processedSizeLocal = 0;
// 18.01 : we don't want ZEROs instead of missing data
if (data)
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
else
processedSizeLocal = numBytesToWrite;
numBytesToWrite = processedSizeLocal; numBytesToWrite = processedSizeLocal;
} }
if (TempBufMode && TempBuf) if (TempBufMode && TempBuf)
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite); {
if (data)
{
memcpy(TempBuf + TempBufWritten, data, numBytesToWrite);
TempBufWritten += numBytesToWrite;
}
}
} }
realProcessed += numBytesToWrite; realProcessed += numBytesToWrite;
if (processedSize) if (processedSize)
*processedSize = realProcessed; *processedSize = realProcessed;
if (data)
data = (const void *)((const Byte *)data + numBytesToWrite); data = (const void *)((const Byte *)data + numBytesToWrite);
size -= numBytesToWrite; size -= numBytesToWrite;
m_RemainFileSize -= numBytesToWrite; m_RemainFileSize -= numBytesToWrite;
@@ -773,7 +786,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
m_FileIsOpen = true; m_FileIsOpen = true;
m_CurrentIndex++; m_CurrentIndex++;
if (result == S_OK && m_RealOutStream && TempBuf) if (result == S_OK && m_RealOutStream && TempBuf)
result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset)); result = WriteStream(m_RealOutStream, TempBuf, TempBufWritten);
if (!TempBuf && TempBufMode && m_RealOutStream) if (!TempBuf && TempBufMode && m_RealOutStream)
{ {
@@ -822,6 +835,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
realProcessed += numBytesToWrite; realProcessed += numBytesToWrite;
if (processedSize) if (processedSize)
*processedSize = realProcessed; *processedSize = realProcessed;
if (data)
data = (const void *)((const Byte *)data + numBytesToWrite); data = (const void *)((const Byte *)data + numBytesToWrite);
size -= numBytesToWrite; size -= numBytesToWrite;
m_PosInFolder += numBytesToWrite; m_PosInFolder += numBytesToWrite;
@@ -843,12 +857,6 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
} }
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
return Write2(data, size, processedSize, true);
}
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
{ {
if (!NeedMoreWrite()) if (!NeedMoreWrite())
@@ -862,19 +870,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
return S_OK; return S_OK;
} }
const unsigned kBufSize = (1 << 12);
Byte buf[kBufSize];
for (unsigned i = 0; i < kBufSize; i++)
buf[i] = 0;
for (;;) for (;;)
{ {
if (!NeedMoreWrite()) if (!NeedMoreWrite())
return S_OK; return S_OK;
UInt64 remain = GetRemain(); UInt64 remain = GetRemain();
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize); UInt32 size = (UInt32)1 << 20;
if (size > remain)
size = (UInt32)remain;
UInt32 processedSizeLocal = 0; UInt32 processedSizeLocal = 0;
RINOK(Write2(buf, size, &processedSizeLocal, false)); RINOK(Write(NULL, size, &processedSizeLocal));
} }
} }

View File

@@ -219,6 +219,7 @@ class CHandler:
bool _masterCrcError; bool _masterCrcError;
bool _headersError; bool _headersError;
UInt32 _dataStartOffset;
UInt64 _startPos; UInt64 _startPos;
UInt64 _phySize; UInt64 _phySize;
@@ -333,6 +334,7 @@ static const Byte kProps[] =
kpidCRC, kpidCRC,
kpidComment, kpidComment,
kpidMethod kpidMethod
// kpidOffset
}; };
IMP_IInArchive_Props IMP_IInArchive_Props
@@ -631,17 +633,40 @@ bool CHandler::ParseBlob(const CByteBuffer &data)
HRESULT CHandler::Open2(IInStream *stream) HRESULT CHandler::Open2(IInStream *stream)
{ {
/*
- usual dmg contains Koly Header at the end:
- rare case dmg contains Koly Header at the start.
*/
_dataStartOffset = 0;
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos)); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos));
UInt64 fileSize = 0;
RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
RINOK(stream->Seek(_startPos, STREAM_SEEK_SET, NULL));
Byte buf[HEADER_SIZE]; Byte buf[HEADER_SIZE];
RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE));
UInt64 headerPos; UInt64 headerPos;
bool startKolyMode = false;
if (IsKoly(buf)) if (IsKoly(buf))
{
// it can be normal koly-at-the-end or koly-at-the-start
headerPos = _startPos; headerPos = _startPos;
if (_startPos <= (1 << 8))
{
// we want to support startKolyMode, even if there is
// some data before dmg file, like 128 bytes MacBin header
_dataStartOffset = HEADER_SIZE;
startKolyMode = true;
}
}
else else
{ {
RINOK(stream->Seek(0, STREAM_SEEK_END, &headerPos)); // we check only koly-at-the-end
headerPos = fileSize;
if (headerPos < HEADER_SIZE) if (headerPos < HEADER_SIZE)
return S_FALSE; return S_FALSE;
headerPos -= HEADER_SIZE; headerPos -= HEADER_SIZE;
@@ -667,24 +692,35 @@ HRESULT CHandler::Open2(IInStream *stream)
// CChecksum dataForkChecksum; // CChecksum dataForkChecksum;
// dataForkChecksum.Parse(buf + 0x50); // dataForkChecksum.Parse(buf + 0x50);
_startPos = 0;
UInt64 top = 0; UInt64 top = 0;
if (!dataForkPair.UpdateTop(headerPos, top)) return S_FALSE; UInt64 limit = startKolyMode ? fileSize : headerPos;
if (!xmlPair.UpdateTop(headerPos, top)) return S_FALSE;
if (!rsrcPair.UpdateTop(headerPos, top)) return S_FALSE; if (!dataForkPair.UpdateTop(limit, top)) return S_FALSE;
if (!xmlPair.UpdateTop(limit, top)) return S_FALSE;
if (!rsrcPair.UpdateTop(limit, top)) return S_FALSE;
/* Some old dmg files contain garbage data in blobPair field. /* Some old dmg files contain garbage data in blobPair field.
So we need to ignore such garbage case; So we need to ignore such garbage case;
And we still need to detect offset of start of archive for "parser" mode. */ And we still need to detect offset of start of archive for "parser" mode. */
bool useBlob = blobPair.UpdateTop(headerPos, top); bool useBlob = blobPair.UpdateTop(limit, top);
_startPos = 0;
if (startKolyMode)
_phySize = top;
else
{
_phySize = headerPos + HEADER_SIZE; _phySize = headerPos + HEADER_SIZE;
_startPos = 0;
if (top != headerPos) if (top != headerPos)
{ {
/*
if expected absolute offset is not equal to real header offset,
2 cases are possible:
- additional (unknown) headers
- archive with offset.
So we try to read XML with absolute offset to select from these two ways.
*/
CForkPair xmlPair2 = xmlPair; CForkPair xmlPair2 = xmlPair;
const char *sz = "<?xml version"; const char *sz = "<?xml version";
const unsigned len = (unsigned)strlen(sz); const unsigned len = (unsigned)strlen(sz);
@@ -694,10 +730,12 @@ HRESULT CHandler::Open2(IInStream *stream)
if (ReadData(stream, xmlPair2, buf2) != S_OK if (ReadData(stream, xmlPair2, buf2) != S_OK
|| memcmp(buf2, sz, len) != 0) || memcmp(buf2, sz, len) != 0)
{ {
// if absolute offset is not OK, probably it's archive with offset
_startPos = headerPos - top; _startPos = headerPos - top;
_phySize = top + HEADER_SIZE; _phySize = top + HEADER_SIZE;
} }
} }
}
// Byte reserved[0x78] // Byte reserved[0x78]
@@ -1041,6 +1079,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
} }
/*
case kpidOffset:
{
prop = item.StartPos;
break;
}
*/
case kpidMethod: case kpidMethod:
{ {
CMethods m; CMethods m;
@@ -1384,7 +1430,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break; break;
} }
RINOK(_inStream->Seek(_startPos + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); RINOK(_inStream->Seek(_startPos + _dataStartOffset + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL));
streamSpec->Init(block.PackSize); streamSpec->Init(block.PackSize);
bool realMethod = true; bool realMethod = true;
outStreamSpec->Init(block.UnpSize); outStreamSpec->Init(block.UnpSize);
@@ -1781,7 +1827,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
spec->Stream = _inStream; spec->Stream = _inStream;
spec->Size = spec->File->Size; spec->Size = spec->File->Size;
RINOK(spec->InitAndSeek(_startPos)); RINOK(spec->InitAndSeek(_startPos + _dataStartOffset));
*stream = specStream.Detach(); *stream = specStream.Detach();
return S_OK; return S_OK;

View File

@@ -567,6 +567,7 @@ static const char * const g_Machines[] =
static const CUInt32PCharPair g_MachinePairs[] = static const CUInt32PCharPair g_MachinePairs[] =
{ {
{ 243, "RISC-V" },
{ 47787, "Xilinx MicroBlaze" } { 47787, "Xilinx MicroBlaze" }
// { 0x9026, "Alpha" } // { 0x9026, "Alpha" }
}; };

View File

@@ -317,11 +317,15 @@ public:
// bool CaseSensetive; // bool CaseSensetive;
UString ResFileName; UString ResFileName;
UInt64 SpecOffset;
UInt64 PhySize; UInt64 PhySize;
UInt64 PhySize2;
void Clear() void Clear()
{ {
SpecOffset = 0;
PhySize = 0; PhySize = 0;
PhySize2 = 0;
HeadersError = false; HeadersError = false;
ThereAreAltStreams = false; ThereAreAltStreams = false;
// CaseSensetive = false; // CaseSensetive = false;
@@ -444,7 +448,7 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt
e.NumBlocks > fork.NumBlocks - curBlock || e.NumBlocks > fork.NumBlocks - curBlock ||
e.NumBlocks > Header.NumBlocks - e.Pos) e.NumBlocks > Header.NumBlocks - e.Pos)
return S_FALSE; return S_FALSE;
RINOK(inStream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(inStream, RINOK(ReadStream_FALSE(inStream,
(Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog),
(size_t)e.NumBlocks << Header.BlockSizeLog)); (size_t)e.NumBlocks << Header.BlockSizeLog));
@@ -1154,13 +1158,36 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
} }
static const unsigned kHeaderPadSize = (1 << 10); static const unsigned kHeaderPadSize = (1 << 10);
static const unsigned kMainHeaderSize = 512;
static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize;
API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
{
if (size < kHfsHeaderSize)
return k_IsArc_Res_NEED_MORE;
p += kHeaderPadSize;
if (p[0] == 'B' && p[1] == 'D')
{
if (p[0x7C] != 'H' || p[0x7C + 1] != '+')
return k_IsArc_Res_NO;
}
else
{
if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
return k_IsArc_Res_NO;
UInt32 version = Get16(p + 2);
if (version < 4 || version > 5)
return k_IsArc_Res_NO;
}
return k_IsArc_Res_YES;
}
}
HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
{ {
Clear(); Clear();
static const unsigned kHeaderSize = kHeaderPadSize + 512; Byte buf[kHfsHeaderSize];
Byte buf[kHeaderSize]; RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize));
RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize));
{ {
for (unsigned i = 0; i < kHeaderPadSize; i++) for (unsigned i = 0; i < kHeaderPadSize; i++)
if (buf[i] != 0) if (buf[i] != 0)
@@ -1171,6 +1198,67 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
h.Header[0] = p[0]; h.Header[0] = p[0];
h.Header[1] = p[1]; h.Header[1] = p[1];
if (p[0] == 'B' && p[1] == 'D')
{
/*
It's header for old HFS format.
We don't support old HFS format, but we support
special HFS volume that contains embedded HFS+ volume
*/
if (p[0x7C] != 'H' || p[0x7C + 1] != '+')
return S_FALSE;
/*
h.CTime = Get32(p + 0x2);
h.MTime = Get32(p + 0x6);
h.NumFiles = Get32(p + 0x54);
h.NumFolders = Get32(p + 0x58);
if (h.NumFolders > ((UInt32)1 << 29) ||
h.NumFiles > ((UInt32)1 << 30))
return S_FALSE;
if (progress)
{
UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
RINOK(progress->SetTotal(&numFiles, NULL));
}
h.NumFreeBlocks = Get16(p + 0x22);
*/
UInt32 blockSize = Get32(p + 0x14);
{
unsigned i;
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
if (i == 31)
return S_FALSE;
h.BlockSizeLog = i;
}
h.NumBlocks = Get16(p + 0x12);
/*
we suppose that it has the follwing layout
{
start block with header
[h.NumBlocks]
end block with header
}
*/
PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog;
UInt32 startBlock = Get16(p + 0x7C + 2);
UInt32 blockCount = Get16(p + 0x7C + 4);
SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog;
UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog);
if (PhySize2 < phy)
PhySize2 = phy;
RINOK(inStream->Seek(SpecOffset, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize));
}
if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
return S_FALSE; return S_FALSE;
h.Version = Get16(p + 2); h.Version = Get16(p + 2);
@@ -1330,7 +1418,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
case kpidExtension: prop = Header.IsHfsX() ? "hfsx" : "hfs"; break; case kpidExtension: prop = Header.IsHfsX() ? "hfsx" : "hfs"; break;
case kpidMethod: prop = Header.IsHfsX() ? "HFSX" : "HFS+"; break; case kpidMethod: prop = Header.IsHfsX() ? "HFSX" : "HFS+"; break;
case kpidPhySize: prop = PhySize; break; case kpidPhySize:
{
UInt64 v = SpecOffset + PhySize;
if (v < PhySize2)
v = PhySize2;
prop = v;
break;
}
case kpidClusterSize: prop = (UInt32)1 << Header.BlockSizeLog; break; case kpidClusterSize: prop = (UInt32)1 << Header.BlockSizeLog; break;
case kpidFreeSpace: prop = (UInt64)Header.GetFreeSize(); break; case kpidFreeSpace: prop = (UInt64)Header.GetFreeSize(); break;
case kpidMTime: HfsTimeToProp(Header.MTime, prop); break; case kpidMTime: HfsTimeToProp(Header.MTime, prop); break;
@@ -1754,7 +1849,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (fork.Size == pos) if (fork.Size == pos)
break; break;
const CExtent &e = fork.Extents[extentIndex]; const CExtent &e = fork.Extents[extentIndex];
RINOK(_stream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL));
UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog; UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog;
while (extentRem != 0) while (extentRem != 0)
{ {
@@ -1865,6 +1960,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
} }
static const Byte k_Signature[] = { static const Byte k_Signature[] = {
2, 'B', 'D',
4, 'H', '+', 0, 4, 4, 'H', '+', 0, 4,
4, 'H', 'X', 0, 5 }; 4, 'H', 'X', 0, 5 };
@@ -1873,6 +1969,6 @@ REGISTER_ARC_I(
k_Signature, k_Signature,
kHeaderPadSize, kHeaderPadSize,
NArcInfoFlags::kMultiSignature, NArcInfoFlags::kMultiSignature,
NULL) IsArc_HFS)
}} }}

View File

@@ -2201,6 +2201,11 @@ bool CHeader::ParseCoff(const Byte *p)
return false; return false;
if (OptHeaderSize != 0 && OptHeaderSize < k_OptHeader32_Size_MIN) if (OptHeaderSize != 0 && OptHeaderSize < k_OptHeader32_Size_MIN)
return false; return false;
// 18.04: we reduce false detections
if (NumSections == 0 && OptHeaderSize == 0)
return false;
for (unsigned i = 0; i < ARRAY_SIZE(g_MachinePairs); i++) for (unsigned i = 0; i < ARRAY_SIZE(g_MachinePairs); i++)
if (Machine == g_MachinePairs[i].Value) if (Machine == g_MachinePairs[i].Value)
return true; return true;

View File

@@ -139,10 +139,9 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val)
{ {
*val = 0; *val = 0;
for (unsigned i = 0; i < maxSize;) for (unsigned i = 0; i < maxSize && i < 10;)
{ {
Byte b = p[i]; Byte b = p[i];
if (i < 10)
*val |= (UInt64)(b & 0x7F) << (7 * i); *val |= (UInt64)(b & 0x7F) << (7 * i);
i++; i++;
if ((b & 0x80) == 0) if ((b & 0x80) == 0)
@@ -1363,7 +1362,9 @@ static const Byte kProps[] =
kpidCharacts, kpidCharacts,
kpidSymLink, kpidSymLink,
kpidHardLink, kpidHardLink,
kpidCopyLink kpidCopyLink,
kpidVolumeIndex
}; };
@@ -1794,6 +1795,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSplitBefore: prop = item.IsSplitBefore(); break; case kpidSplitBefore: prop = item.IsSplitBefore(); break;
case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break; case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break;
case kpidVolumeIndex:
{
if (item.VolIndex < _arcs.Size())
{
const CInArcInfo &arcInfo = _arcs[item.VolIndex].Info;
if (arcInfo.IsVolume())
prop = (UInt64)arcInfo.GetVolIndex();
}
break;
}
case kpidCRC: case kpidCRC:
{ {
const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem); const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem);

View File

@@ -180,7 +180,7 @@ struct CItem
AString Name; AString Name;
int VolIndex; unsigned VolIndex;
int NextItem; int NextItem;
UInt32 UnixMTime; UInt32 UnixMTime;

View File

@@ -777,7 +777,9 @@ static const Byte kProps[] =
kpidCRC, kpidCRC,
kpidHostOS, kpidHostOS,
kpidMethod, kpidMethod,
kpidUnpackVer kpidUnpackVer,
kpidVolumeIndex
}; };
static const Byte kArcProps[] = static const Byte kArcProps[] =
@@ -995,6 +997,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
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 kpidVolumeIndex:
if (_arcInfo.Is_VolNumber_Defined())
prop = (UInt32)(_arcInfo.VolNumber + refItem.VolumeIndex);
break;
case kpidCRC: case kpidCRC:
{ {
prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);

View File

@@ -26,7 +26,7 @@ struct CInArcInfo
UInt32 DataCRC; UInt32 DataCRC;
bool EndOfArchive_was_Read; bool EndOfArchive_was_Read;
CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {} CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false), VolNumber(0) {}
UInt64 GetPhySize() const { return EndPos - StartPos; } UInt64 GetPhySize() const { return EndPos - StartPos; }

View File

@@ -94,7 +94,9 @@ static bool ParseInt64(const char *p, Int64 &val)
static bool ParseInt64_MTime(const char *p, Int64 &val) static bool ParseInt64_MTime(const char *p, Int64 &val)
{ {
// rare case tar contains spaces instead of MTime // rare case tar : ZEROs in Docker-Windows TARs
// rare case tar : spaces
if (GetUi32(p) != 0)
for (unsigned i = 0; i < 12; i++) for (unsigned i = 0; i < 12; i++)
if (p[i] != ' ') if (p[i] != ' ')
return ParseInt64(p, val); return ParseInt64(p, val);

View File

@@ -1993,6 +1993,13 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
} }
else if (ext.IsEqualTo_Ascii_NoCase("exe")) else if (ext.IsEqualTo_Ascii_NoCase("exe"))
{ {
/* possible cases:
- exe with zip inside
- sfx: a.exe, a.z02, a.z03,... , a.zip
a.exe is start volume.
- zip renamed to exe
*/
StartIsExe = true; StartIsExe = true;
BaseName = name; BaseName = name;
StartVolIndex = 0; StartVolIndex = 0;
@@ -2000,7 +2007,22 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
We can open arc.zip, if it was requesed to open arc.exe. We can open arc.zip, if it was requesed to open arc.exe.
But it's possible that arc.exe and arc.zip are not parts of same archive. But it's possible that arc.exe and arc.zip are not parts of same archive.
So we can disable such operation */ So we can disable such operation */
return S_FALSE; // don't open arc.zip instead of arc.exe
// 18.04: we still want to open zip renamed to exe.
/*
{
UString volName = name;
volName += IsUpperCase ? "Z01" : "z01";
{
CMyComPtr<IInStream> stream;
HRESULT res2 = volCallback->GetStream(volName, &stream);
if (res2 == S_OK)
DisableVolsSearch = true;
}
}
*/
DisableVolsSearch = true;
return S_OK;
} }
else if (ext[0] == 'z' || ext[0] == 'Z') else if (ext[0] == 'z' || ext[0] == 'Z')
{ {
@@ -2040,6 +2062,9 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback, HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols) unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols)
{ {
if (Vols.DisableVolsSearch)
return S_OK;
numMissingVols = 0; numMissingVols = 0;
for (unsigned i = start;; i++) for (unsigned i = start;; i++)
@@ -2090,6 +2115,8 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
} }
if (res == S_FALSE || !stream) if (res == S_FALSE || !stream)
{ {
if (i == 1 && Vols.StartIsExe)
return S_OK;
if (Vols.MissingName.IsEmpty()) if (Vols.MissingName.IsEmpty())
Vols.MissingName = volName; Vols.MissingName = volName;
numMissingVols++; numMissingVols++;

View File

@@ -162,6 +162,7 @@ struct CVols
bool NeedSeek; bool NeedSeek;
bool DisableVolsSearch;
bool StartIsExe; // is .exe bool StartIsExe; // is .exe
bool StartIsZ; // is .zip or .zNN bool StartIsZ; // is .zip or .zNN
bool StartIsZip; // is .zip bool StartIsZip; // is .zip
@@ -201,6 +202,7 @@ struct CVols
StreamIndex = -1; StreamIndex = -1;
NeedSeek = false; NeedSeek = false;
DisableVolsSearch = false;
StartIsExe = false; StartIsExe = false;
StartIsZ = false; StartIsZ = false;
StartIsZip = false; StartIsZip = false;

View File

@@ -1112,18 +1112,6 @@ SOURCE=..\..\Compress\ShrinkDecoder.cpp
SOURCE=..\..\Compress\ShrinkDecoder.h SOURCE=..\..\Compress\ShrinkDecoder.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Z"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\ZDecoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Compress\ZDecoder.h
# End Source File
# End Group
# Begin Group "BWT" # Begin Group "BWT"
# PROP Default_Filter "" # PROP Default_Filter ""
@@ -1648,10 +1636,6 @@ SOURCE=..\..\Archive\SplitHandler.cpp
SOURCE=..\..\Archive\XzHandler.cpp SOURCE=..\..\Archive\XzHandler.cpp
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\Archive\ZHandler.cpp
# End Source File
# End Group # End Group
# Begin Group "UI Common" # Begin Group "UI Common"

View File

@@ -75,7 +75,6 @@ AR_OBJS = \
$O\LzmaHandler.obj \ $O\LzmaHandler.obj \
$O\SplitHandler.obj \ $O\SplitHandler.obj \
$O\XzHandler.obj \ $O\XzHandler.obj \
$O\ZHandler.obj \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
@@ -169,7 +168,6 @@ COMPRESS_OBJS = \
$O\ShrinkDecoder.obj \ $O\ShrinkDecoder.obj \
$O\XzDecoder.obj \ $O\XzDecoder.obj \
$O\XzEncoder.obj \ $O\XzEncoder.obj \
$O\ZDecoder.obj \
CRYPTO_OBJS = \ CRYPTO_OBJS = \
$O\7zAes.obj \ $O\7zAes.obj \

View File

@@ -1,3 +1,7 @@
#include "../../MyVersionInfo.rc" #include "../../MyVersionInfo.rc"
MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za") MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
#ifndef UNDER_CE
1 24 MOVEABLE PURE "../../UI/Console/Console.manifest"
#endif

View File

@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /FAc /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAc /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -69,7 +69,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # 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 BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c # ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -94,7 +94,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c
# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -121,7 +121,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c # ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -482,6 +482,14 @@ SOURCE=..\..\..\Windows\FileName.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\FileSystem.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileSystem.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Handle.h SOURCE=..\..\..\Windows\Handle.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -3,7 +3,7 @@ MY_CONSOLE = 1
CFLAGS = $(CFLAGS) -DPROG_VARIANT_R CFLAGS = $(CFLAGS) -DPROG_VARIANT_R
!IFNDEF UNDER_CE !IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
!ENDIF !ENDIF
COMMON_OBJS = \ COMMON_OBJS = \
@@ -33,6 +33,7 @@ WIN_OBJS = \
$O\FileIO.obj \ $O\FileIO.obj \
$O\FileLink.obj \ $O\FileLink.obj \
$O\FileName.obj \ $O\FileName.obj \
$O\FileSystem.obj \
$O\MemoryLock.obj \ $O\MemoryLock.obj \
$O\PropVariant.obj \ $O\PropVariant.obj \
$O\PropVariantConv.obj \ $O\PropVariantConv.obj \

View File

@@ -1,3 +1,7 @@
#include "../../../../C/7zVersion.rc" #include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr") MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr")
#ifndef UNDER_CE
1 24 MOVEABLE PURE "../../UI/Console/Console.manifest"
#endif

View File

@@ -677,6 +677,14 @@ SOURCE=..\..\UI\FileManager\DialogSize.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\FileManager\EditDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\EditDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\LinkDialog.cpp SOURCE=..\..\UI\FileManager\LinkDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1567,14 +1575,6 @@ SOURCE=..\..\..\Common\Wildcard.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\ArchiveCommandLine.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -48,7 +48,6 @@ WIN_CTRL_OBJS = \
$O\FileStreams.obj \ $O\FileStreams.obj \
UI_COMMON_OBJS = \ UI_COMMON_OBJS = \
$O\ArchiveCommandLine.obj \
$O\ArchiveExtractCallback.obj \ $O\ArchiveExtractCallback.obj \
$O\ArchiveName.obj \ $O\ArchiveName.obj \
$O\ArchiveOpenCallback.obj \ $O\ArchiveOpenCallback.obj \

View File

@@ -117,10 +117,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\Common\HandlerOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Common\HandlerOut.h SOURCE=..\..\Archive\Common\HandlerOut.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -1,5 +1,7 @@
PROG = 7zCon.sfx PROG = 7zCon.sfx
MY_CONSOLE = 1 MY_CONSOLE = 1
MY_FIXED = 1
CFLAGS = $(CFLAGS) \ CFLAGS = $(CFLAGS) \
-DEXTRACT_ONLY \ -DEXTRACT_ONLY \
-DNO_READ_FROM_CODER \ -DNO_READ_FROM_CODER \

View File

@@ -1,4 +1,6 @@
PROG = 7zS.sfx PROG = 7zS.sfx
MY_FIXED = 1
CFLAGS = $(CFLAGS) \ CFLAGS = $(CFLAGS) \
-DNO_REGISTRY \ -DNO_REGISTRY \
-DEXTRACT_ONLY \ -DEXTRACT_ONLY \

View File

@@ -1,4 +1,6 @@
PROG = 7z.sfx PROG = 7z.sfx
MY_FIXED = 1
CFLAGS = $(CFLAGS) \ CFLAGS = $(CFLAGS) \
-DNO_REGISTRY \ -DNO_REGISTRY \
-DEXTRACT_ONLY \ -DEXTRACT_ONLY \

View File

@@ -22,7 +22,7 @@ namespace NLzma2 {
CEncoder::CEncoder() CEncoder::CEncoder()
{ {
_encoder = NULL; _encoder = NULL;
_encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc);
if (!_encoder) if (!_encoder)
throw 1; throw 1;
} }

View File

@@ -15,7 +15,7 @@ namespace NLzma {
CEncoder::CEncoder() CEncoder::CEncoder()
{ {
_encoder = NULL; _encoder = NULL;
_encoder = LzmaEnc_Create(&g_Alloc); _encoder = LzmaEnc_Create(&g_AlignedAlloc);
if (!_encoder) if (!_encoder)
throw 1; throw 1;
} }
@@ -23,7 +23,7 @@ CEncoder::CEncoder()
CEncoder::~CEncoder() CEncoder::~CEncoder()
{ {
if (_encoder) if (_encoder)
LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc); LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc);
} }
static inline wchar_t GetUpperChar(wchar_t c) static inline wchar_t GetUpperChar(wchar_t c)
@@ -168,7 +168,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
progressWrap.Init(progress); progressWrap.Init(progress);
SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
progress ? &progressWrap.vt : NULL, &g_Alloc, &g_BigAlloc); progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc);
_inputProcessed = inWrap.Processed; _inputProcessed = inWrap.Processed;

View File

@@ -9,77 +9,85 @@
namespace NCompress { namespace NCompress {
namespace NRar1 { namespace NRar1 {
static const UInt32 PosL1[] = {0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; static const unsigned kNumBits = 12;
static const UInt32 PosL2[] = {0,0,0,0,5,7,9,13,18,22,26,34,36, 256};
static const UInt32 PosHf0[] = {0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; static const Byte kShortLen1[16 * 3] =
static const UInt32 PosHf1[] = {0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; {
static const UInt32 PosHf2[] = {0,0,0,0,0,0,2,7,53,117,233, 257,0}; 0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0,0,
static const UInt32 PosHf3[] = {0,0,0,0,0,0,0,2,16,218,251, 257,0}; 1,3,4,4,5,6,7,8,8,4,4,5,6,6,0,0,
static const UInt32 PosHf4[] = {0,0,0,0,0,0,0,0,0,255, 257,0,0}; 1,4,4,4,5,6,7,8,8,4,4,5,6,6,4,0
};
static const Byte kShortLen2[16 * 3] =
{
0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0,0,
2,3,3,3,4,4,5,6,6,4,4,5,6,6,0,0,
2,3,3,4,4,4,5,6,6,4,4,5,6,6,4,0
};
static const Byte PosL1[kNumBits + 1] = { 0,0,2,1,2,2,4,5,4,4,8,0,224 };
static const Byte PosL2[kNumBits + 1] = { 0,0,0,5,2,2,4,5,4,4,8,2,220 };
static const Byte PosHf0[kNumBits + 1] = { 0,0,0,0,8,8,8,9,0,0,0,0,224 };
static const Byte PosHf1[kNumBits + 1] = { 0,0,0,0,0,4,40,16,16,4,0,47,130 };
static const Byte PosHf2[kNumBits + 1] = { 0,0,0,0,0,2,5,46,64,116,24,0,0 };
static const Byte PosHf3[kNumBits + 1] = { 0,0,0,0,0,0,2,14,202,33,6,0,0 };
static const Byte PosHf4[kNumBits + 1] = { 0,0,0,0,0,0,0,0,255,2,0,0,0 };
static const UInt32 kHistorySize = (1 << 16); static const UInt32 kHistorySize = (1 << 16);
/* CDecoder::CDecoder():
class CCoderReleaser _isSolid(false),
{ _solidAllowed(false)
CDecoder *m_Coder; { }
public:
CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
};
*/
CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); }
void CDecoder::InitStructures()
{
for (int i = 0; i < kNumRepDists; i++)
m_RepDists[i] = 0;
m_RepDistPtr = 0;
LastLength = 0;
LastDist = 0;
}
UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len)
{ {
if (len == 0) if (len == 0)
return S_FALSE; return S_FALSE;
if (m_UnpackSize < len)
return S_FALSE;
m_UnpackSize -= len; m_UnpackSize -= len;
return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE;
} }
UInt32 CDecoder::DecodeNum(const UInt32 *posTab) UInt32 CDecoder::DecodeNum(const Byte *numTab)
{ {
UInt32 startPos = 2; /*
UInt32 num = m_InBitStream.GetValue(12); {
// we can check that tables are correct
UInt32 sum = 0;
for (unsigned i = 0; i <= kNumBits; i++)
sum += ((UInt32)numTab[i] << (kNumBits - i));
if (sum != (1 << kNumBits))
throw 111;
}
*/
UInt32 val = m_InBitStream.GetValue(kNumBits);
UInt32 sum = 0;
unsigned i = 2;
for (;;) for (;;)
{ {
UInt32 cur = (posTab[(size_t)startPos + 1] - posTab[startPos]) << (12 - startPos); UInt32 num = numTab[i];
if (num < cur) UInt32 cur = num << (kNumBits - i);
if (val < cur)
break; break;
startPos++; i++;
num -= cur; val -= cur;
sum += num;
} }
m_InBitStream.MovePos(startPos); m_InBitStream.MovePos(i);
return((num >> (12 - startPos)) + posTab[startPos]); return ((val >> (kNumBits - i)) + sum);
} }
static const Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 };
static const Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 };
static const Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 };
static const Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 };
static const UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
static const UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
HRESULT CDecoder::ShortLZ() HRESULT CDecoder::ShortLZ()
{ {
UInt32 len, saveLen, dist;
int distancePlace;
const Byte *kShortLen;
const UInt32 *kShortXor;
NumHuf = 0; NumHuf = 0;
if (LCount == 2) if (LCount == 2)
@@ -91,19 +99,13 @@ HRESULT CDecoder::ShortLZ()
UInt32 bitField = m_InBitStream.GetValue(8); UInt32 bitField = m_InBitStream.GetValue(8);
if (AvrLn1 < 37) UInt32 len, dist;
{ {
kShortLen = Buf60 ? kShortLen1a : kShortLen1; const Byte *xors = (AvrLn1 < 37) ? kShortLen1 : kShortLen2;
kShortXor = kShortXor1; const Byte *lens = xors + 16 + Buf60;
for (len = 0; ((bitField ^ xors[len]) >> (8 - lens[len])) != 0; len++);
m_InBitStream.MovePos(lens[len]);
} }
else
{
kShortLen = Buf60 ? kShortLen2a : kShortLen2;
kShortXor = kShortXor2;
}
for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++);
m_InBitStream.MovePos(kShortLen[len]);
if (len >= 9) if (len >= 9)
{ {
@@ -112,9 +114,11 @@ HRESULT CDecoder::ShortLZ()
LCount++; LCount++;
return CopyBlock(LastDist, LastLength); return CopyBlock(LastDist, LastLength);
} }
LCount = 0;
if (len == 14) if (len == 14)
{ {
LCount = 0;
len = DecodeNum(PosL2) + 5; len = DecodeNum(PosL2) + 5;
dist = 0x8000 + ReadBits(15) - 1; dist = 0x8000 + ReadBits(15) - 1;
LastLength = len; LastLength = len;
@@ -122,41 +126,46 @@ HRESULT CDecoder::ShortLZ()
return CopyBlock(dist, len); return CopyBlock(dist, len);
} }
LCount = 0; UInt32 saveLen = len;
saveLen = len;
dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3];
len = DecodeNum(PosL1) + 2;
if (len == 0x101 && saveLen == 10) len = DecodeNum(PosL1);
if (len == 0xff && saveLen == 10)
{ {
Buf60 ^= 1; Buf60 ^= 16;
return S_OK; return S_OK;
} }
if (dist >= 256) if (dist >= 256)
{
len++; len++;
if (dist >= MaxDist3 - 1) if (dist >= MaxDist3 - 1)
len++; len++;
} }
}
else else
{ {
LCount = 0; LCount = 0;
AvrLn1 += len; AvrLn1 += len;
AvrLn1 -= AvrLn1 >> 4; AvrLn1 -= AvrLn1 >> 4;
distancePlace = DecodeNum(PosHf2) & 0xff; unsigned distancePlace = DecodeNum(PosHf2) & 0xff;
dist = ChSetA[(unsigned)distancePlace];
if (--distancePlace != -1) dist = ChSetA[distancePlace];
if (distancePlace != 0)
{ {
PlaceA[dist]--; PlaceA[dist]--;
UInt32 lastDistance = ChSetA[(unsigned)distancePlace]; UInt32 lastDistance = ChSetA[(size_t)distancePlace - 1];
PlaceA[lastDistance]++; PlaceA[lastDistance]++;
ChSetA[(size_t)(unsigned)distancePlace + 1] = lastDistance; ChSetA[distancePlace] = lastDistance;
ChSetA[(unsigned)distancePlace] = dist; ChSetA[(size_t)distancePlace - 1] = dist;
} }
len += 2;
} }
m_RepDists[m_RepDistPtr++] = dist; m_RepDists[m_RepDistPtr++] = dist;
m_RepDistPtr &= 3; m_RepDistPtr &= 3;
len += 2;
LastLength = len; LastLength = len;
LastDist = dist; LastDist = dist;
return CopyBlock(dist, len); return CopyBlock(dist, len);
@@ -177,12 +186,10 @@ HRESULT CDecoder::LongLZ()
Nlzb = 0x90; Nlzb = 0x90;
Nhfb >>= 1; Nhfb >>= 1;
} }
oldAvr2=AvrLn2; oldAvr2 = AvrLn2;
if (AvrLn2 >= 122) if (AvrLn2 >= 64)
len = DecodeNum(PosL2); len = DecodeNum(AvrLn2 < 122 ? PosL1 : PosL2);
else if (AvrLn2 >= 64)
len = DecodeNum(PosL1);
else else
{ {
UInt32 bitField = m_InBitStream.GetValue(16); UInt32 bitField = m_InBitStream.GetValue(16);
@@ -193,8 +200,8 @@ HRESULT CDecoder::LongLZ()
} }
else else
{ {
for (len = 0; ((bitField << len) & 0x8000) == 0; len++) for (len = 0; ((bitField << len) & 0x8000) == 0; len++);
;
m_InBitStream.MovePos(len + 1); m_InBitStream.MovePos(len + 1);
} }
} }
@@ -202,24 +209,26 @@ HRESULT CDecoder::LongLZ()
AvrLn2 += len; AvrLn2 += len;
AvrLn2 -= AvrLn2 >> 5; AvrLn2 -= AvrLn2 >> 5;
if (AvrPlcB > 0x28ff) {
distancePlace = DecodeNum(PosHf2); const Byte *tab;
else if (AvrPlcB > 0x6ff) if (AvrPlcB >= 0x2900) tab = PosHf2;
distancePlace = DecodeNum(PosHf1); else if (AvrPlcB >= 0x0700) tab = PosHf1;
else else tab = PosHf0;
distancePlace = DecodeNum(PosHf0); distancePlace = DecodeNum(tab); // [0, 256]
}
AvrPlcB += distancePlace; AvrPlcB += distancePlace;
AvrPlcB -= AvrPlcB >> 8; AvrPlcB -= AvrPlcB >> 8;
distancePlace &= 0xff;
for (;;) for (;;)
{ {
dist = ChSetB[distancePlace & 0xff]; dist = ChSetB[distancePlace];
newDistancePlace = NToPlB[dist++ & 0xff]++; newDistancePlace = NToPlB[dist++ & 0xff]++;
if (!(dist & 0xff)) if (dist & 0xff)
CorrHuff(ChSetB,NToPlB);
else
break; break;
CorrHuff(ChSetB,NToPlB);
} }
ChSetB[distancePlace] = ChSetB[newDistancePlace]; ChSetB[distancePlace] = ChSetB[newDistancePlace];
@@ -235,8 +244,7 @@ HRESULT CDecoder::LongLZ()
AvrLn3++; AvrLn3++;
AvrLn3 -= AvrLn3 >> 8; AvrLn3 -= AvrLn3 >> 8;
} }
else else if (AvrLn3 > 0)
if (AvrLn3 > 0)
AvrLn3--; AvrLn3--;
len += 3; len += 3;
@@ -265,57 +273,62 @@ HRESULT CDecoder::HuffDecode()
UInt32 curByte, newBytePlace; UInt32 curByte, newBytePlace;
UInt32 len; UInt32 len;
UInt32 dist; UInt32 dist;
int bytePlace; unsigned bytePlace;
{
const Byte *tab;
if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4); if (AvrPlc >= 0x7600) tab = PosHf4;
else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3); else if (AvrPlc >= 0x5e00) tab = PosHf3;
else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); else if (AvrPlc >= 0x3600) tab = PosHf2;
else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); else if (AvrPlc >= 0x0e00) tab = PosHf1;
else bytePlace = DecodeNum(PosHf0); else tab = PosHf0;
bytePlace = DecodeNum(tab); // [0, 256]
}
if (StMode) if (StMode)
{ {
if (--bytePlace == -1) if (bytePlace == 0)
{ {
if (ReadBits(1)) if (ReadBits(1))
{ {
NumHuf = StMode = 0; NumHuf = 0;
StMode = false;
return S_OK; return S_OK;
} }
else len = ReadBits(1) + 3;
{
len = (ReadBits(1)) ? 4 : 3;
dist = DecodeNum(PosHf2); dist = DecodeNum(PosHf2);
dist = (dist << 5) | ReadBits(5); dist = (dist << 5) | ReadBits(5);
if (dist == 0)
return S_FALSE;
return CopyBlock(dist - 1, len); return CopyBlock(dist - 1, len);
} }
} bytePlace--; // bytePlace is [0, 255]
} }
else if (NumHuf++ >= 16 && FlagsCnt == 0) else if (NumHuf++ >= 16 && FlagsCnt == 0)
StMode = 1; StMode = true;
bytePlace &= 0xff; bytePlace &= 0xff;
AvrPlc += bytePlace; AvrPlc += bytePlace;
AvrPlc -= AvrPlc >> 8; AvrPlc -= AvrPlc >> 8;
Nhfb+=16; Nhfb += 16;
if (Nhfb > 0xff) if (Nhfb > 0xff)
{ {
Nhfb=0x90; Nhfb = 0x90;
Nlzb >>= 1; Nlzb >>= 1;
} }
m_UnpackSize --; m_UnpackSize--;
m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8));
for (;;) for (;;)
{ {
curByte = ChSet[bytePlace]; curByte = ChSet[bytePlace];
newBytePlace = NToPl[curByte++ & 0xff]++; newBytePlace = NToPl[curByte++ & 0xff]++;
if ((curByte & 0xff) > 0xa1) if ((curByte & 0xff) <= 0xa1)
CorrHuff(ChSet, NToPl);
else
break; break;
CorrHuff(ChSet, NToPl);
} }
ChSet[bytePlace] = ChSet[newBytePlace]; ChSet[bytePlace] = ChSet[newBytePlace];
@@ -327,7 +340,10 @@ HRESULT CDecoder::HuffDecode()
void CDecoder::GetFlagsBuf() void CDecoder::GetFlagsBuf()
{ {
UInt32 flags, newFlagsPlace; UInt32 flags, newFlagsPlace;
UInt32 flagsPlace = DecodeNum(PosHf2); UInt32 flagsPlace = DecodeNum(PosHf2); // [0, 256]
if (flagsPlace >= ARRAY_SIZE(ChSetC))
return;
for (;;) for (;;)
{ {
@@ -343,20 +359,6 @@ void CDecoder::GetFlagsBuf()
ChSetC[newFlagsPlace] = flags; ChSetC[newFlagsPlace] = flags;
} }
void CDecoder::InitData()
{
if (!m_IsSolid)
{
AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
AvrPlc = 0x3500;
MaxDist3 = 0x2001;
Nhfb = Nlzb = 0x80;
}
FlagsCnt = 0;
FlagBuf = 0;
StMode = 0;
LCount = 0;
}
void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
{ {
@@ -369,50 +371,70 @@ void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
NumToPlace[i] = (7 - i) * 32; NumToPlace[i] = (7 - i) * 32;
} }
void CDecoder::InitHuff()
{
for (UInt32 i = 0; i < 256; i++)
{
Place[i] = PlaceA[i] = PlaceB[i] = i;
PlaceC[i] = (~i + 1) & 0xff;
ChSet[i] = ChSetB[i] = i << 8;
ChSetA[i] = i;
ChSetC[i] = ((~i + 1) & 0xff) << 8;
}
memset(NToPl, 0, sizeof(NToPl));
memset(NToPlB, 0, sizeof(NToPlB));
memset(NToPlC, 0, sizeof(NToPlC));
CorrHuff(ChSetB, NToPlB);
}
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */) const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */)
{ {
if (inSize == NULL || outSize == NULL) if (!inSize || !outSize)
return E_INVALIDARG; return E_INVALIDARG;
if (_isSolid && !_solidAllowed)
return S_FALSE;
_solidAllowed = false;
if (!m_OutWindowStream.Create(kHistorySize)) if (!m_OutWindowStream.Create(kHistorySize))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if (!m_InBitStream.Create(1 << 20)) if (!m_InBitStream.Create(1 << 20))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
m_UnpackSize = (Int64)*outSize; m_UnpackSize = *outSize;
m_OutWindowStream.SetStream(outStream); m_OutWindowStream.SetStream(outStream);
m_OutWindowStream.Init(m_IsSolid); m_OutWindowStream.Init(_isSolid);
m_InBitStream.SetStream(inStream); m_InBitStream.SetStream(inStream);
m_InBitStream.Init(); m_InBitStream.Init();
// CCoderReleaser coderReleaser(this); // InitData
InitData();
if (!m_IsSolid) FlagsCnt = 0;
FlagBuf = 0;
StMode = false;
LCount = 0;
if (!_isSolid)
{ {
_errorMode = false; AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
InitStructures(); AvrPlc = 0x3500;
InitHuff(); MaxDist3 = 0x2001;
Nhfb = Nlzb = 0x80;
{
// InitStructures
for (int i = 0; i < kNumRepDists; i++)
m_RepDists[i] = 0;
m_RepDistPtr = 0;
LastLength = 0;
LastDist = 0;
} }
if (_errorMode) // InitHuff
return S_FALSE;
for (UInt32 i = 0; i < 256; i++)
{
Place[i] = PlaceA[i] = PlaceB[i] = i;
UInt32 c = (~i + 1) & 0xff;
PlaceC[i] = c;
ChSet[i] = ChSetB[i] = i << 8;
ChSetA[i] = i;
ChSetC[i] = c << 8;
}
memset(NToPl, 0, sizeof(NToPl));
memset(NToPlB, 0, sizeof(NToPlB));
memset(NToPlC, 0, sizeof(NToPlC));
CorrHuff(ChSetB, NToPlB);
}
if (m_UnpackSize > 0) if (m_UnpackSize > 0)
{ {
@@ -420,78 +442,74 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
FlagsCnt = 8; FlagsCnt = 8;
} }
while (m_UnpackSize > 0) while (m_UnpackSize != 0)
{ {
if (StMode) if (!StMode)
{ {
RINOK(HuffDecode());
continue;
}
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt=7;
}
if (FlagBuf & 0x80)
{
FlagBuf <<= 1;
if (Nlzb > Nhfb)
{
RINOK(LongLZ());
}
else
{
RINOK(HuffDecode());
}
}
else
{
FlagBuf <<= 1;
if (--FlagsCnt < 0) if (--FlagsCnt < 0)
{ {
GetFlagsBuf(); GetFlagsBuf();
FlagsCnt = 7; FlagsCnt = 7;
} }
if (FlagBuf & 0x80) if (FlagBuf & 0x80)
{ {
FlagBuf <<= 1; FlagBuf <<= 1;
if (Nlzb > Nhfb) if (Nlzb > Nhfb)
{
RINOK(HuffDecode());
}
else
{ {
RINOK(LongLZ()); RINOK(LongLZ());
continue;
} }
} }
else else
{
FlagBuf <<= 1;
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt = 7;
}
if ((FlagBuf & 0x80) == 0)
{ {
FlagBuf <<= 1; FlagBuf <<= 1;
RINOK(ShortLZ()); RINOK(ShortLZ());
continue;
}
FlagBuf <<= 1;
if (Nlzb <= Nhfb)
{
RINOK(LongLZ());
continue;
} }
} }
} }
if (m_UnpackSize < 0)
return S_FALSE; RINOK(HuffDecode());
}
_solidAllowed = true;
return m_OutWindowStream.Flush(); return m_OutWindowStream.Flush();
} }
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{ {
try { return CodeReal(inStream, outStream, inSize, outSize, progress); } try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } catch(const CInBufferException &e) { return e.ErrorCode; }
catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; } catch(const CLzOutWindowException &e) { return e.ErrorCode; }
catch(...) { _errorMode = true; return S_FALSE; } catch(...) { return S_FALSE; }
} }
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{ {
if (size < 1) if (size < 1)
return E_INVALIDARG; return E_INVALIDARG;
m_IsSolid = ((data[0] & 1) != 0); _isSolid = ((data[0] & 1) != 0);
return S_OK; return S_OK;
} }

View File

@@ -20,49 +20,45 @@ namespace NRar1 {
const UInt32 kNumRepDists = 4; const UInt32 kNumRepDists = 4;
typedef NBitm::CDecoder<CInBuffer> CBitDecoder;
class CDecoder : class CDecoder :
public ICompressCoder, public ICompressCoder,
public ICompressSetDecoderProperties2, public ICompressSetDecoderProperties2,
public CMyUnknownImp public CMyUnknownImp
{ {
public:
CLzOutWindow m_OutWindowStream; CLzOutWindow m_OutWindowStream;
CBitDecoder m_InBitStream; NBitm::CDecoder<CInBuffer> m_InBitStream;
UInt32 m_RepDists[kNumRepDists]; UInt64 m_UnpackSize;
UInt32 m_RepDistPtr;
UInt32 LastDist; UInt32 LastDist;
UInt32 LastLength; UInt32 LastLength;
Int64 m_UnpackSize; UInt32 m_RepDistPtr;
bool m_IsSolid; UInt32 m_RepDists[kNumRepDists];
bool _errorMode;
UInt32 ReadBits(int numBits); bool _isSolid;
bool _solidAllowed;
bool StMode;
int FlagsCnt;
UInt32 FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
unsigned Buf60, NumHuf, LCount;
UInt32 Nhfb, Nlzb, MaxDist3;
UInt32 ChSet[256], ChSetA[256], ChSetB[256], ChSetC[256];
UInt32 Place[256], PlaceA[256], PlaceB[256], PlaceC[256];
UInt32 NToPl[256], NToPlB[256], NToPlC[256];
UInt32 ReadBits(unsigned numBits);
HRESULT CopyBlock(UInt32 distance, UInt32 len); HRESULT CopyBlock(UInt32 distance, UInt32 len);
UInt32 DecodeNum(const Byte *numTab);
UInt32 DecodeNum(const UInt32 *posTab);
HRESULT ShortLZ(); HRESULT ShortLZ();
HRESULT LongLZ(); HRESULT LongLZ();
HRESULT HuffDecode(); HRESULT HuffDecode();
void GetFlagsBuf(); void GetFlagsBuf();
void InitData();
void InitHuff();
void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace); void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace);
void OldUnpWriteBuf(); void OldUnpWriteBuf();
UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
UInt32 NToPl[256],NToPlB[256],NToPlC[256];
UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
int Buf60,NumHuf,StMode,LCount,FlagsCnt;
UInt32 Nhfb,Nlzb,MaxDist3;
void InitStructures();
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
@@ -71,14 +67,6 @@ public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
/*
void ReleaseStreams()
{
m_OutWindowStream.ReleaseStream();
m_InBitStream.ReleaseStream();
}
*/
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
static const UInt32 kWindowReservSize = (1 << 22) + 256; static const UInt32 kWindowReservSize = (1 << 22) + 256;
CDecoder::CDecoder(): CDecoder::CDecoder():
m_IsSolid(false), _isSolid(false),
_solidAllowed(false),
m_TablesOK(false) m_TablesOK(false)
{ {
} }
@@ -227,18 +228,6 @@ bool CDecoder::ReadLastTables()
return true; return true;
} }
/*
class CCoderReleaser
{
CDecoder *m_Coder;
public:
CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
~CCoderReleaser()
{
m_Coder->ReleaseStreams();
}
};
*/
bool CDecoder::DecodeMm(UInt32 pos) bool CDecoder::DecodeMm(UInt32 pos)
{ {
@@ -343,9 +332,13 @@ bool CDecoder::DecodeLz(Int32 pos)
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{ {
if (inSize == NULL || outSize == NULL) if (!inSize || !outSize)
return E_INVALIDARG; return E_INVALIDARG;
if (_isSolid && !_solidAllowed)
return S_FALSE;
_solidAllowed = false;
if (!m_OutWindowStream.Create(kHistorySize)) if (!m_OutWindowStream.Create(kHistorySize))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if (!m_InBitStream.Create(1 << 20)) if (!m_InBitStream.Create(1 << 20))
@@ -356,12 +349,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
UInt64 pos = 0, unPackSize = *outSize; UInt64 pos = 0, unPackSize = *outSize;
m_OutWindowStream.SetStream(outStream); m_OutWindowStream.SetStream(outStream);
m_OutWindowStream.Init(m_IsSolid); m_OutWindowStream.Init(_isSolid);
m_InBitStream.SetStream(inStream); m_InBitStream.SetStream(inStream);
m_InBitStream.Init(); m_InBitStream.Init();
// CCoderReleaser coderReleaser(this); // CCoderReleaser coderReleaser(this);
if (!m_IsSolid) if (!_isSolid)
{ {
InitStructures(); InitStructures();
if (unPackSize == 0) if (unPackSize == 0)
@@ -369,6 +362,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
if (!ReadTables()) if (!ReadTables())
return S_FALSE; return S_FALSE;
_solidAllowed = true;
return S_OK; return S_OK;
} }
ReadTables(); ReadTables();
@@ -415,6 +409,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
if (!ReadLastTables()) if (!ReadLastTables())
return S_FALSE; return S_FALSE;
_solidAllowed = true;
return m_OutWindowStream.Flush(); return m_OutWindowStream.Flush();
} }
@@ -431,7 +428,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{ {
if (size < 1) if (size < 1)
return E_INVALIDARG; return E_INVALIDARG;
m_IsSolid = ((data[0] & 1) != 0); _isSolid = ((data[0] & 1) != 0);
return S_OK; return S_OK;
} }

View File

@@ -125,7 +125,8 @@ class CDecoder :
UInt32 m_LastLength; UInt32 m_LastLength;
bool m_IsSolid; bool _isSolid;
bool _solidAllowed;
bool m_TablesOK; bool m_TablesOK;
bool m_AudioMode; bool m_AudioMode;
@@ -159,14 +160,6 @@ public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
/*
void ReleaseStreams()
{
m_OutWindowStream.ReleaseStream();
m_InBitStream.ReleaseStream();
}
*/
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -94,8 +94,8 @@ CDecoder::CDecoder():
_writtenFileSize(0), _writtenFileSize(0),
_vmData(0), _vmData(0),
_vmCode(0), _vmCode(0),
m_IsSolid(false), _isSolid(false),
_errorMode(false) _solidAllowed(false)
{ {
Ppmd7_Construct(&_ppmd); Ppmd7_Construct(&_ppmd);
} }
@@ -829,7 +829,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
_writtenFileSize = 0; _writtenFileSize = 0;
_unsupportedFilter = false; _unsupportedFilter = false;
if (!m_IsSolid) if (!_isSolid)
{ {
_lzSize = 0; _lzSize = 0;
_winPos = 0; _winPos = 0;
@@ -842,19 +842,24 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
PpmEscChar = 2; PpmEscChar = 2;
PpmError = true; PpmError = true;
InitFilters(); InitFilters();
_errorMode = false; // _errorMode = false;
} }
/*
if (_errorMode) if (_errorMode)
return S_FALSE; return S_FALSE;
*/
if (!m_IsSolid || !TablesRead) if (!_isSolid || !TablesRead)
{ {
bool keepDecompressing; bool keepDecompressing;
RINOK(ReadTables(keepDecompressing)); RINOK(ReadTables(keepDecompressing));
if (!keepDecompressing) if (!keepDecompressing)
{
_solidAllowed = true;
return S_OK; return S_OK;
} }
}
for (;;) for (;;)
{ {
@@ -878,6 +883,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
if (!keepDecompressing) if (!keepDecompressing)
break; break;
} }
_solidAllowed = true;
RINOK(WriteBuf()); RINOK(WriteBuf());
UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
@@ -898,6 +906,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
if (!inSize) if (!inSize)
return E_INVALIDARG; return E_INVALIDARG;
if (_isSolid && !_solidAllowed)
return S_FALSE;
_solidAllowed = false;
if (!_vmData) if (!_vmData)
{ {
_vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
@@ -926,8 +938,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
_unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
return CodeReal(progress); return CodeReal(progress);
} }
catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } catch(const CInBufferException &e) { /* _errorMode = true; */ return e.ErrorCode; }
catch(...) { _errorMode = true; return S_FALSE; } catch(...) { /* _errorMode = true; */ return S_FALSE; }
// CNewException is possible here. But probably CNewException is caused // CNewException is possible here. But probably CNewException is caused
// by error in data stream. // by error in data stream.
} }
@@ -936,7 +948,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{ {
if (size < 1) if (size < 1)
return E_INVALIDARG; return E_INVALIDARG;
m_IsSolid = ((data[0] & 1) != 0); _isSolid = ((data[0] & 1) != 0);
return S_OK; return S_OK;
} }

View File

@@ -191,8 +191,9 @@ class CDecoder:
CRecordVector<CTempFilter *> _tempFilters; CRecordVector<CTempFilter *> _tempFilters;
UInt32 _lastFilter; UInt32 _lastFilter;
bool m_IsSolid; bool _isSolid;
bool _errorMode; bool _solidAllowed;
// bool _errorMode;
bool _lzMode; bool _lzMode;
bool _unsupportedFilter; bool _unsupportedFilter;

View File

@@ -72,6 +72,7 @@ CDecoder::CDecoder():
_writtenFileSize(0), _writtenFileSize(0),
_dictSizeLog(0), _dictSizeLog(0),
_isSolid(false), _isSolid(false),
_solidAllowed(false),
_wasInit(false), _wasInit(false),
_inputBuf(NULL) _inputBuf(NULL)
{ {
@@ -334,44 +335,47 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream)
{ {
if (_progress) if (_progress)
{ {
UInt64 packSize = _bitStream.GetProcessedSize(); const UInt64 packSize = _bitStream.GetProcessedSize();
RINOK(_progress->SetRatioInfo(&packSize, &_writtenFileSize)); RINOK(_progress->SetRatioInfo(&packSize, &_writtenFileSize));
} }
_bitStream.AlignToByte(); _bitStream.AlignToByte();
_bitStream.Prepare(); _bitStream.Prepare();
{
unsigned flags = _bitStream.ReadByteInAligned(); unsigned flags = _bitStream.ReadByteInAligned();
unsigned checkSum = _bitStream.ReadByteInAligned(); unsigned checkSum = _bitStream.ReadByteInAligned();
checkSum ^= flags; checkSum ^= flags;
UInt32 blockSize;
{
unsigned num = (flags >> 3) & 3; unsigned num = (flags >> 3) & 3;
if (num == 3) if (num == 3)
return S_FALSE; return S_FALSE;
blockSize = _bitStream.ReadByteInAligned(); UInt32 blockSize = _bitStream.ReadByteInAligned();
if (num > 0) checkSum ^= blockSize;
if (num != 0)
{ {
blockSize += (UInt32)_bitStream.ReadByteInAligned() << 8; unsigned b = _bitStream.ReadByteInAligned();
checkSum ^= b;
blockSize += (UInt32)b << 8;
if (num > 1) if (num > 1)
blockSize += (UInt32)_bitStream.ReadByteInAligned() << 16; {
b = _bitStream.ReadByteInAligned();
checkSum ^= b;
blockSize += (UInt32)b << 16;
} }
} }
checkSum ^= blockSize ^ (blockSize >> 8) ^ (blockSize >> 16); if (checkSum != 0x5A)
if ((Byte)checkSum != 0x5A)
return S_FALSE; return S_FALSE;
unsigned blockSizeBits7 = (flags & 7) + 1; unsigned blockSizeBits7 = (flags & 7) + 1;
if (blockSize == 0 && blockSizeBits7 != 8)
return S_FALSE;
blockSize += (blockSizeBits7 >> 3); blockSize += (blockSizeBits7 >> 3);
if (blockSize == 0)
return S_FALSE;
blockSize--; blockSize--;
blockSizeBits7 &= 7;
_bitStream._blockEndBits7 = (Byte)(blockSizeBits7 & 7); _bitStream._blockEndBits7 = (Byte)blockSizeBits7;
_bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize; _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize;
_bitStream.SetCheck2(); _bitStream.SetCheck2();
@@ -380,12 +384,14 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream)
if ((flags & 0x80) == 0) if ((flags & 0x80) == 0)
{ {
if (!_tableWasFilled && blockSize != 0) if (!_tableWasFilled)
if (blockSize != 0 || blockSizeBits7 != 0)
return S_FALSE; return S_FALSE;
return S_OK; return S_OK;
} }
_tableWasFilled = false; _tableWasFilled = false;
}
{ {
Byte lens2[kLevelTableSize]; Byte lens2[kLevelTableSize];
@@ -596,6 +602,10 @@ HRESULT CDecoder::DecodeLZ()
} }
} }
} }
// that check is not required, but it can help, if there is BUG in another code
if (!_tableWasFilled)
break; // return S_FALSE;
} }
UInt32 sym = m_MainDecoder.Decode(&_bitStream); UInt32 sym = m_MainDecoder.Decode(&_bitStream);
@@ -797,7 +807,10 @@ HRESULT CDecoder::CodeReal()
*/ */
if (res == S_OK) if (res == S_OK)
{
_solidAllowed = true;
res = res2; res = res2;
}
if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize)
return S_FALSE; return S_FALSE;
@@ -817,6 +830,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
{ {
try try
{ {
if (_isSolid && !_solidAllowed)
return S_FALSE;
_solidAllowed = false;
if (_dictSizeLog >= sizeof(size_t) * 8) if (_dictSizeLog >= sizeof(size_t) * 8)
return E_NOTIMPL; return E_NOTIMPL;

View File

@@ -127,7 +127,7 @@ public:
return *_buf++; return *_buf++;
} }
UInt32 GetValue(unsigned numBits) UInt32 GetValue(unsigned numBits) const
{ {
UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2]; UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2];
v >>= (24 - numBits - _bitPos); v >>= (24 - numBits - _bitPos);
@@ -219,6 +219,13 @@ class CDecoder:
bool _lzError; bool _lzError;
bool _writeError; bool _writeError;
bool _isSolid;
bool _solidAllowed;
bool _tableWasFilled;
bool _wasInit;
Byte _dictSizeLog;
// CBitDecoder _bitStream; // CBitDecoder _bitStream;
Byte *_window; Byte *_window;
size_t _winPos; size_t _winPos;
@@ -238,11 +245,6 @@ class CDecoder:
UInt64 _writtenFileSize; UInt64 _writtenFileSize;
size_t _winSizeAllocated; size_t _winSizeAllocated;
Byte _dictSizeLog;
bool _tableWasFilled;
bool _isSolid;
bool _wasInit;
UInt32 _reps[kNumReps]; UInt32 _reps[kNumReps];
UInt32 _lastLen; UInt32 _lastLen;

View File

@@ -30,14 +30,13 @@ CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {}
static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val)
{ {
unsigned i;
*val = 0; *val = 0;
for (i = 0; i < maxSize;) for (unsigned i = 0; i < maxSize && i < 10;)
{ {
Byte b = p[i]; Byte b = p[i];
if (i < 10) *val |= (UInt64)(b & 0x7F) << (7 * i);
*val |= (UInt64)(b & 0x7F) << (7 * i++); i++;
if ((b & 0x80) == 0) if ((b & 0x80) == 0)
return i; return i;
} }

View File

@@ -71,6 +71,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \ DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
#define MY_BUTTON__CLOSE \
DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys
#define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP #define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
#define MY_COMBO_SORTED MY_COMBO | CBS_SORT #define MY_COMBO_SORTED MY_COMBO | CBS_SORT

View File

@@ -8,9 +8,17 @@
#ifndef UNDER_CE #ifndef UNDER_CE
#include <io.h> #include <io.h>
#endif #endif
#else
// for isatty()
#include <unistd.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#ifdef _7ZIP_LARGE_PAGES
#include "../../../../C/Alloc.h"
#endif
#include "../../../Common/ListFileUtils.h" #include "../../../Common/ListFileUtils.h"
#include "../../../Common/StringConvert.h" #include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h" #include "../../../Common/StringToInt.h"
@@ -19,18 +27,20 @@
#include "../../../Windows/FileName.h" #include "../../../Windows/FileName.h"
#ifdef _WIN32 #ifdef _WIN32
#include "../../../Windows/FileMapping.h" #include "../../../Windows/FileMapping.h"
#include "../../../Windows/MemoryLock.h"
#include "../../../Windows/Synchronization.h" #include "../../../Windows/Synchronization.h"
#endif #endif
#include "ArchiveCommandLine.h" #include "ArchiveCommandLine.h"
#include "EnumDirItems.h" #include "EnumDirItems.h"
#include "SortUtils.h"
#include "Update.h" #include "Update.h"
#include "UpdateAction.h" #include "UpdateAction.h"
extern bool g_CaseSensitive; extern bool g_CaseSensitive;
extern bool g_PathTrailReplaceMode; extern bool g_PathTrailReplaceMode;
bool g_LargePagesMode = false;
#ifdef UNDER_CE #ifdef UNDER_CE
#define MY_IS_TERMINAL(x) false; #define MY_IS_TERMINAL(x) false;
@@ -60,15 +70,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v)
return *end == 0; return *end == 0;
} }
CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u)
{
(*this) += a;
if (u)
{
Add_LF();
(*this) += u;
}
}
int g_CodePage = -1; int g_CodePage = -1;
@@ -240,7 +241,7 @@ static const CSwitchForm kSwitchForms[] =
{ "si", NSwitchType::kString }, { "si", NSwitchType::kString },
{ "so" }, { "so" },
{ "slp", NSwitchType::kMinus }, { "slp", NSwitchType::kString },
{ "scs", NSwitchType::kString }, { "scs", NSwitchType::kString },
{ "scc", NSwitchType::kString }, { "scc", NSwitchType::kString },
{ "slt" }, { "slt" },
@@ -282,7 +283,6 @@ static const char * const kIncorrectListFile = "Incorrect item in listfile.\nChe
static const char * const kTerminalOutError = "I won't write compressed data to a terminal"; static const char * const kTerminalOutError = "I won't write compressed data to a terminal";
static const char * const kSameTerminalError = "I won't write data and program's messages to same stream"; static const char * const kSameTerminalError = "I won't write data and program's messages to same stream";
static const char * const kEmptyFilePath = "Empty file path"; static const char * const kEmptyFilePath = "Empty file path";
static const char * const kCannotFindArchive = "Cannot find archive";
bool CArcCommand::IsFromExtractGroup() const bool CArcCommand::IsFromExtractGroup() const
{ {
@@ -615,84 +615,6 @@ static void AddSwitchWildcardsToCensor(
throw CArcCmdLineException(errorMessage, strings[i]); throw CArcCmdLineException(errorMessage, strings[i]);
} }
#ifdef _WIN32
// This code converts all short file names to long file names.
static void ConvertToLongName(const UString &prefix, UString &name)
{
if (name.IsEmpty() || DoesNameContainWildcard(name))
return;
NFind::CFileInfo fi;
const FString path (us2fs(prefix + name));
#ifndef UNDER_CE
if (NFile::NName::IsDevicePath(path))
return;
#endif
if (fi.Find(path))
name = fs2us(fi.Name);
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
{
FOR_VECTOR (i, items)
{
NWildcard::CItem &item = items[i];
if (item.Recursive || item.PathParts.Size() != 1)
continue;
if (prefix.IsEmpty() && item.IsDriveItem())
continue;
ConvertToLongName(prefix, item.PathParts.Front());
}
}
static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
{
ConvertToLongNames(prefix, node.IncludeItems);
ConvertToLongNames(prefix, node.ExcludeItems);
unsigned i;
for (i = 0; i < node.SubNodes.Size(); i++)
{
UString &name = node.SubNodes[i].Name;
if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
continue;
ConvertToLongName(prefix, name);
}
// mix folders with same name
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
for (unsigned j = i + 1; j < node.SubNodes.Size();)
{
const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
{
nextNode1.IncludeItems += nextNode2.IncludeItems;
nextNode1.ExcludeItems += nextNode2.ExcludeItems;
node.SubNodes.Delete(j);
}
else
j++;
}
}
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode = node.SubNodes[i];
ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
}
}
void ConvertToLongNames(NWildcard::CCensor &censor)
{
FOR_VECTOR (i, censor.Pairs)
{
NWildcard::CPair &pair = censor.Pairs[i];
ConvertToLongNames(pair.Prefix, pair.Head);
}
}
#endif
/* /*
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{ {
@@ -922,9 +844,45 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
options.CaseSensitive = g_CaseSensitive; options.CaseSensitive = g_CaseSensitive;
} }
options.LargePages = false;
#if defined(_WIN32) && !defined(UNDER_CE)
NSecurity::EnablePrivilege_SymLink();
#endif
// options.LargePages = false;
if (parser[NKey::kLargePages].ThereIs) if (parser[NKey::kLargePages].ThereIs)
options.LargePages = !parser[NKey::kLargePages].WithMinus; {
unsigned slp = 0;
const UString &s = parser[NKey::kLargePages].PostStrings[0];
if (s.IsEmpty())
slp = 1;
else if (s != L"-")
{
if (!StringToUInt32(s, slp))
throw CArcCmdLineException("Unsupported switch postfix for -slp", s);
}
#ifdef _7ZIP_LARGE_PAGES
if (slp >
#ifndef UNDER_CE
(unsigned)NSecurity::Get_LargePages_RiskLevel()
#else
0
#endif
)
{
SetLargePageSize();
// note: this process also can inherit that Privilege from parent process
g_LargePagesMode =
#if defined(_WIN32) && !defined(UNDER_CE)
NSecurity::EnablePrivilege_LockMemory();
#else
true;
#endif
}
#endif
}
#ifndef UNDER_CE #ifndef UNDER_CE
@@ -996,64 +954,6 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key
} }
} }
HRESULT EnumerateDirItemsAndSort(
NWildcard::CCensor &censor,
NWildcard::ECensorPathMode censorPathMode,
const UString &addPathPrefix,
UStringVector &sortedPaths,
UStringVector &sortedFullPaths,
CDirItemsStat &st,
IDirItemsCallback *callback)
{
FStringVector paths;
{
CDirItems dirItems;
dirItems.Callback = callback;
{
HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
st = dirItems.Stat;
RINOK(res);
}
FOR_VECTOR (i, dirItems.Items)
{
const CDirItem &dirItem = dirItems.Items[i];
if (!dirItem.IsDir())
paths.Add(dirItems.GetPhyPath(i));
}
}
if (paths.Size() == 0)
throw CArcCmdLineException(kCannotFindArchive);
UStringVector fullPaths;
unsigned i;
for (i = 0; i < paths.Size(); i++)
{
FString fullPath;
NFile::NDir::MyGetFullPathName(paths[i], fullPath);
fullPaths.Add(fs2us(fullPath));
}
CUIntVector indices;
SortFileNames(fullPaths, indices);
sortedPaths.ClearAndReserve(indices.Size());
sortedFullPaths.ClearAndReserve(indices.Size());
for (i = 0; i < indices.Size(); i++)
{
unsigned index = indices[i];
sortedPaths.AddInReserved(fs2us(paths[index]));
sortedFullPaths.AddInReserved(fullPaths[index]);
if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]);
}
return S_OK;
}
static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp) static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
{ {

View File

@@ -6,14 +6,13 @@
#include "../../../Common/CommandLineParser.h" #include "../../../Common/CommandLineParser.h"
#include "../../../Common/Wildcard.h" #include "../../../Common/Wildcard.h"
#include "EnumDirItems.h"
#include "Extract.h" #include "Extract.h"
#include "HashCalc.h" #include "HashCalc.h"
#include "Update.h" #include "Update.h"
struct CArcCmdLineException: public UString typedef CMessagePathException CArcCmdLineException;
{
CArcCmdLineException(const char *a, const wchar_t *u = NULL);
};
namespace NCommandType { enum EEnum namespace NCommandType { enum EEnum
{ {
@@ -51,7 +50,7 @@ struct CArcCmdLineOptions
{ {
bool HelpMode; bool HelpMode;
bool LargePages; // bool LargePages;
bool CaseSensitiveChange; bool CaseSensitiveChange;
bool CaseSensitive; bool CaseSensitive;
@@ -110,7 +109,7 @@ struct CArcCmdLineOptions
UInt32 NumIterations; UInt32 NumIterations;
CArcCmdLineOptions(): CArcCmdLineOptions():
LargePages(false), // LargePages(false),
CaseSensitiveChange(false), CaseSensitiveChange(false),
CaseSensitive(false), CaseSensitive(false),
@@ -134,13 +133,4 @@ public:
void Parse2(CArcCmdLineOptions &options); void Parse2(CArcCmdLineOptions &options);
}; };
HRESULT EnumerateDirItemsAndSort(
NWildcard::CCensor &censor,
NWildcard::ECensorPathMode pathMode,
const UString &addPathPrefix,
UStringVector &sortedPaths,
UStringVector &sortedFullPaths,
CDirItemsStat &st,
IDirItemsCallback *callback);
#endif #endif

View File

@@ -2602,7 +2602,8 @@ static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
PrintHex(s, si.wProcessorLevel); PrintHex(s, si.wProcessorLevel);
s += "."; s += ".";
PrintHex(s, si.wProcessorRevision); PrintHex(s, si.wProcessorRevision);
if (si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors)) if ((UInt64)si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors))
if ((UInt64)si.dwActiveProcessorMask + 1 != 0 || si.dwNumberOfProcessors != sizeof(UInt64) * 8)
{ {
s += " act:"; s += " act:";
PrintHex(s, si.dwActiveProcessorMask); PrintHex(s, si.dwActiveProcessorMask);
@@ -2686,14 +2687,16 @@ void GetCpuName(AString &s)
AString s2; AString s2;
x86cpuid_to_String(cpuid, s2); x86cpuid_to_String(cpuid, s2);
s += s2; s += s2;
return;
} }
else
{
#ifdef MY_CPU_AMD64 #ifdef MY_CPU_AMD64
s += "x64"; s += "x64";
#else #else
s += "x86"; s += "x86";
#endif #endif
} }
}
#else #else
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
@@ -2703,6 +2706,9 @@ void GetCpuName(AString &s)
#endif #endif
#endif #endif
if (g_LargePagesMode)
s += " (LP)";
} }
@@ -2725,6 +2731,27 @@ void GetCpuFeatures(AString &s)
} }
#ifdef _WIN32
#ifndef UNDER_CE
typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi)
{
HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
if (!ntdll)
return FALSE;
Func_RtlGetVersion func = (Func_RtlGetVersion)GetProcAddress(ntdll, "RtlGetVersion");
if (!func)
return FALSE;
func(vi);
return TRUE;
}
#endif
#endif
HRESULT Bench( HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback, IBenchPrintCallback *printCallback,
@@ -2859,6 +2886,30 @@ HRESULT Bench(
if (printCallback) if (printCallback)
{ {
#ifdef _WIN32
#ifndef UNDER_CE
{
AString s;
// OSVERSIONINFO vi;
OSVERSIONINFOEXW vi;
vi.dwOSVersionInfoSize = sizeof(vi);
// if (::GetVersionEx(&vi))
if (My_RtlGetVersion(&vi))
{
s += "Windows";
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
s.Add_UInt32(vi.dwPlatformId);
s += " "; s.Add_UInt32(vi.dwMajorVersion);
s += "."; s.Add_UInt32(vi.dwMinorVersion);
s += " "; s.Add_UInt32(vi.dwBuildNumber);
// s += " "; s += GetAnsiString(vi.szCSDVersion);
}
printCallback->Print(s);
printCallback->NewLine();
}
#endif
#endif
{ {
AString s1, s2; AString s1, s2;
GetSysInfo(s1, s2); GetSysInfo(s1, s2);

View File

@@ -13,6 +13,7 @@
#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileDir.h" #include "../../../Windows/FileDir.h"
#include "../../../Windows/FileMapping.h" #include "../../../Windows/FileMapping.h"
#include "../../../Windows/MemoryLock.h"
#include "../../../Windows/ProcessUtils.h" #include "../../../Windows/ProcessUtils.h"
#include "../../../Windows/Synchronization.h" #include "../../../Windows/Synchronization.h"
@@ -94,6 +95,9 @@ static HRESULT Call7zGui(const UString &params,
static void AddLagePagesSwitch(UString &params) static void AddLagePagesSwitch(UString &params)
{ {
if (ReadLockMemoryEnable()) if (ReadLockMemoryEnable())
#ifndef UNDER_CE
if (NSecurity::Get_LargePages_RiskLevel() == 0)
#endif
params += " -slp"; params += " -slp";
} }

View File

@@ -1,10 +1,10 @@
// CompressCall.cpp // CompressCall2.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../Common/MyException.h" #include "../../../Common/MyException.h"
#include "../../UI/common/ArchiveCommandLine.h" #include "../../UI/Common/EnumDirItems.h"
#include "../../UI/GUI/BenchmarkDialog.h" #include "../../UI/GUI/BenchmarkDialog.h"
#include "../../UI/GUI/ExtractGUI.h" #include "../../UI/GUI/ExtractGUI.h"
@@ -20,6 +20,7 @@ extern HWND g_HWND;
#define MY_TRY_BEGIN HRESULT result; try { #define MY_TRY_BEGIN HRESULT result; try {
#define MY_TRY_FINISH } \ #define MY_TRY_FINISH } \
catch(CSystemException &e) { result = e.ErrorCode; } \ catch(CSystemException &e) { result = e.ErrorCode; } \
catch(UString &s) { ErrorMessage(s); result = E_FAIL; } \
catch(...) { result = E_FAIL; } \ catch(...) { result = E_FAIL; } \
if (result != S_OK && result != E_ABORT) \ if (result != S_OK && result != E_ABORT) \
ErrorMessageHRESULT(result); ErrorMessageHRESULT(result);

View File

@@ -16,6 +16,7 @@
#endif #endif
#include "EnumDirItems.h" #include "EnumDirItems.h"
#include "SortUtils.h"
using namespace NWindows; using namespace NWindows;
using namespace NFile; using namespace NFile;
@@ -925,3 +926,161 @@ void CDirItems::FillFixedReparse()
} }
#endif #endif
static const char * const kCannotFindArchive = "Cannot find archive";
HRESULT EnumerateDirItemsAndSort(
NWildcard::CCensor &censor,
NWildcard::ECensorPathMode censorPathMode,
const UString &addPathPrefix,
UStringVector &sortedPaths,
UStringVector &sortedFullPaths,
CDirItemsStat &st,
IDirItemsCallback *callback)
{
FStringVector paths;
{
CDirItems dirItems;
dirItems.Callback = callback;
{
HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
st = dirItems.Stat;
RINOK(res);
}
FOR_VECTOR (i, dirItems.Items)
{
const CDirItem &dirItem = dirItems.Items[i];
if (!dirItem.IsDir())
paths.Add(dirItems.GetPhyPath(i));
}
}
if (paths.Size() == 0)
{
// return S_OK;
throw CMessagePathException(kCannotFindArchive);
}
UStringVector fullPaths;
unsigned i;
for (i = 0; i < paths.Size(); i++)
{
FString fullPath;
NFile::NDir::MyGetFullPathName(paths[i], fullPath);
fullPaths.Add(fs2us(fullPath));
}
CUIntVector indices;
SortFileNames(fullPaths, indices);
sortedPaths.ClearAndReserve(indices.Size());
sortedFullPaths.ClearAndReserve(indices.Size());
for (i = 0; i < indices.Size(); i++)
{
unsigned index = indices[i];
sortedPaths.AddInReserved(fs2us(paths[index]));
sortedFullPaths.AddInReserved(fullPaths[index]);
if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]);
}
return S_OK;
}
#ifdef _WIN32
// This code converts all short file names to long file names.
static void ConvertToLongName(const UString &prefix, UString &name)
{
if (name.IsEmpty() || DoesNameContainWildcard(name))
return;
NFind::CFileInfo fi;
const FString path (us2fs(prefix + name));
#ifndef UNDER_CE
if (NFile::NName::IsDevicePath(path))
return;
#endif
if (fi.Find(path))
name = fs2us(fi.Name);
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
{
FOR_VECTOR (i, items)
{
NWildcard::CItem &item = items[i];
if (item.Recursive || item.PathParts.Size() != 1)
continue;
if (prefix.IsEmpty() && item.IsDriveItem())
continue;
ConvertToLongName(prefix, item.PathParts.Front());
}
}
static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
{
ConvertToLongNames(prefix, node.IncludeItems);
ConvertToLongNames(prefix, node.ExcludeItems);
unsigned i;
for (i = 0; i < node.SubNodes.Size(); i++)
{
UString &name = node.SubNodes[i].Name;
if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
continue;
ConvertToLongName(prefix, name);
}
// mix folders with same name
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
for (unsigned j = i + 1; j < node.SubNodes.Size();)
{
const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
{
nextNode1.IncludeItems += nextNode2.IncludeItems;
nextNode1.ExcludeItems += nextNode2.ExcludeItems;
node.SubNodes.Delete(j);
}
else
j++;
}
}
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode = node.SubNodes[i];
ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
}
}
void ConvertToLongNames(NWildcard::CCensor &censor)
{
FOR_VECTOR (i, censor.Pairs)
{
NWildcard::CPair &pair = censor.Pairs[i];
ConvertToLongNames(pair.Prefix, pair.Head);
}
}
#endif
CMessagePathException::CMessagePathException(const char *a, const wchar_t *u)
{
(*this) += a;
if (u)
{
Add_LF();
(*this) += u;
}
}

View File

@@ -18,4 +18,24 @@ HRESULT EnumerateItems(
const UString &addPathPrefix, const UString &addPathPrefix,
CDirItems &dirItems); CDirItems &dirItems);
struct CMessagePathException: public UString
{
CMessagePathException(const char *a, const wchar_t *u = NULL);
};
HRESULT EnumerateDirItemsAndSort(
NWildcard::CCensor &censor,
NWildcard::ECensorPathMode pathMode,
const UString &addPathPrefix,
UStringVector &sortedPaths,
UStringVector &sortedFullPaths,
CDirItemsStat &st,
IDirItemsCallback *callback);
#ifdef _WIN32
void ConvertToLongNames(NWildcard::CCensor &censor);
#endif
#endif #endif

View File

@@ -9,7 +9,6 @@
#include "../../Common/MethodProps.h" #include "../../Common/MethodProps.h"
#include "DirItem.h" #include "DirItem.h"
#include "Property.h"
const unsigned k_HashCalc_DigestSize_Max = 64; const unsigned k_HashCalc_DigestSize_Max = 64;

View File

@@ -992,7 +992,7 @@ static void MakeCheckOrder(CCodecs *codecs,
int index = orderIndices[i]; int index = orderIndices[i];
if (index < 0) if (index < 0)
continue; continue;
const CArcInfoEx &ai = codecs->Formats[index]; const CArcInfoEx &ai = codecs->Formats[(unsigned)index];
if (ai.SignatureOffset != 0) if (ai.SignatureOffset != 0)
{ {
orderIndices2.Add(index); orderIndices2.Add(index);
@@ -2295,7 +2295,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
int index = orderIndices[i]; int index = orderIndices[i];
if (index < 0) if (index < 0)
continue; continue;
const CArcInfoEx &ai = op.codecs->Formats[index]; const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
bool isDifficult = false; bool isDifficult = false;
// if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
if (!ai.NewInterface) if (!ai.NewInterface)
@@ -2327,7 +2327,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (isDifficult) if (isDifficult)
{ {
difficultFormats.Add(index); difficultFormats.Add(index);
difficultBools[index] = true; difficultBools[(unsigned)index] = true;
} }
} }

View File

@@ -369,7 +369,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1); int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1);
if (index >= 0) if (index >= 0)
{ {
s += sid_32_Names[index].sz; s += sid_32_Names[(unsigned)index].sz;
return; return;
} }
} }
@@ -379,7 +379,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4); int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4);
if (index >= 0) if (index >= 0)
{ {
s += sid_21_Names[index].sz; s += sid_21_Names[(unsigned)index].sz;
return; return;
} }
} }
@@ -630,7 +630,7 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
{ {
int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag); int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag);
if (index >= 0) if (index >= 0)
s += k_ReparseTags[index].sz; s += k_ReparseTags[(unsigned)index].sz;
else else
{ {
s += "REPARSE:"; s += "REPARSE:";

View File

@@ -1046,10 +1046,6 @@ static HRESULT EnumerateInArchiveItems(
#endif #endif
#ifdef _WIN32
void ConvertToLongNames(NWildcard::CCensor &censor);
#endif
HRESULT UpdateArchive( HRESULT UpdateArchive(
CCodecs *codecs, CCodecs *codecs,
const CObjectVector<COpenType> &types, const CObjectVector<COpenType> &types,

View File

@@ -0,0 +1,13 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7z" type="win32"></assemblyIdentity>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false">
</requestedExecutionLevel></requestedPrivileges></security></trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
</assembly>

View File

@@ -60,8 +60,9 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
if (_se) if (_se)
{ {
*_se << endl << kError << NError::MyFormatMessage(systemError) << endl << *_se << endl << kError << NError::MyFormatMessage(systemError) << endl;
fs2us(path) << endl << endl; _se->NormalizePrint_UString(fs2us(path));
*_se << endl << endl;
_se->Flush(); _se->Flush();
} }
return HRESULT_FROM_WIN32(systemError); return HRESULT_FROM_WIN32(systemError);
@@ -251,7 +252,9 @@ static const char * const kTab = " ";
static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size)
{ {
*_so << kTab << "Path: " << path << endl; *_so << kTab << "Path: ";
_so->NormalizePrint_wstr(path);
*_so << endl;
if (size && *size != (UInt64)(Int64)-1) if (size && *size != (UInt64)(Int64)-1)
{ {
AString s; AString s;
@@ -340,7 +343,10 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
_tempU.Empty(); _tempU.Empty();
if (name) if (name)
{
_tempU = name; _tempU = name;
_so->Normalize_UString(_tempU);
}
_so->PrintUString(_tempU, _tempA); _so->PrintUString(_tempU, _tempA);
if (position) if (position)
*_so << " <" << *position << ">"; *_so << " <" << *position << ">";
@@ -461,7 +467,10 @@ STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encr
*_se << s; *_se << s;
if (!_currentName.IsEmpty()) if (!_currentName.IsEmpty())
*_se << " : " << _currentName; {
*_se << " : ";
_se->NormalizePrint_UString(_currentName);
}
*_se << endl; *_se << endl;
_se->Flush(); _se->Flush();
} }
@@ -513,7 +522,11 @@ HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode)
ClosePercents_for_so(); ClosePercents_for_so();
if (_so) if (_so)
*_so << endl << (testMode ? kTesting : kExtracting) << name << endl; {
*_so << endl << (testMode ? kTesting : kExtracting);
_so->NormalizePrint_wstr(name);
*_so << endl;
}
if (NeedPercents()) if (NeedPercents())
_percent.Command = "Open"; _percent.Command = "Open";
@@ -573,8 +586,9 @@ void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, c
{ {
const CArcErrorInfo &er = arc.ErrorInfo; const CArcErrorInfo &er = arc.ErrorInfo;
UString s ("WARNING:\n"); *_so << "WARNING:\n";
s += arc.Path; _so->NormalizePrint_UString(arc.Path);
UString s;
if (arc.FormatIndex == er.ErrorFormatIndex) if (arc.FormatIndex == er.ErrorFormatIndex)
{ {
s.Add_LF(); s.Add_LF();
@@ -619,7 +633,10 @@ HRESULT CExtractCallbackConsole::OpenResult(
{ {
*_se << endl; *_se << endl;
if (level != 0) if (level != 0)
*_se << arc.Path << endl; {
_se->NormalizePrint_UString(arc.Path);
*_se << endl;
}
} }
if (errorFlags != 0) if (errorFlags != 0)
@@ -653,7 +670,10 @@ HRESULT CExtractCallbackConsole::OpenResult(
{ {
*_so << endl; *_so << endl;
if (level != 0) if (level != 0)
*_so << arc.Path << endl; {
_so->NormalizePrint_UString(arc.Path);
*_so << endl;
}
} }
if (warningFlags != 0) if (warningFlags != 0)
@@ -708,7 +728,9 @@ HRESULT CExtractCallbackConsole::OpenResult(
_so->Flush(); _so->Flush();
if (_se) if (_se)
{ {
*_se << kError << name << endl; *_se << kError;
_se->NormalizePrint_wstr(name);
*_se << endl;
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
RINOK(res); RINOK(res);
if (result == S_FALSE) if (result == S_FALSE)

View File

@@ -269,7 +269,7 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun
if (_fileName.IsEmpty()) if (_fileName.IsEmpty())
*_so << kEmptyFileAlias; *_so << kEmptyFileAlias;
else else
*_so << _fileName; _so->NormalizePrint_UString(_fileName);
} }
*_so << endl; *_so << endl;
} }

View File

@@ -560,7 +560,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
{ {
if (!techMode) if (!techMode)
g_StdOut << temp; g_StdOut << temp;
g_StdOut.PrintUString(FilePath, TempAString); g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString);
if (techMode) if (techMode)
g_StdOut << MY_ENDL; g_StdOut << MY_ENDL;
continue; continue;
@@ -671,9 +671,10 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
else if (prop.vt == VT_BSTR) else if (prop.vt == VT_BSTR)
{ {
TempWString.SetFromBstr(prop.bstrVal); TempWString.SetFromBstr(prop.bstrVal);
// do we need multi-line support here ?
g_StdOut.Normalize_UString(TempWString);
if (techMode) if (techMode)
{ {
// replace CR/LF here.
g_StdOut.PrintUString(TempWString, TempAString); g_StdOut.PrintUString(TempWString, TempAString);
} }
else else
@@ -815,9 +816,63 @@ static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int6
so << val << endl; so << val << endl;
} }
static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val)
static void UString_Replace_CRLF_to_LF(UString &s)
{ {
so << name << " = " << val << endl; // s.Replace(L"\r\n", L"\n");
wchar_t *src = s.GetBuf();
wchar_t *dest = src;
for (;;)
{
wchar_t c = *src++;
if (c == 0)
break;
if (c == '\r' && *src == '\n')
{
src++;
c = '\n';
}
*dest++ = c;
}
s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf()));
}
static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val)
{
UString s = val;
if (s.Find(L'\n') >= 0)
{
so << endl;
so << "{";
so << endl;
UString_Replace_CRLF_to_LF(s);
so.Normalize_UString__LF_Allowed(s);
so << s;
so << endl;
so << "}";
}
else
{
so.Normalize_UString(s);
so << s;
}
so << endl;
}
static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine)
{
so << name << " = ";
if (multiLine)
{
PrintPropVal_MultiLine(so, val);
return;
}
UString s = val;
so.Normalize_UString(s);
so << s;
so << endl;
} }
@@ -831,9 +886,11 @@ static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *
UString nameU; UString nameU;
GetPropName(propID, name, nameA, nameU); GetPropName(propID, name, nameA, nameU);
if (!nameA.IsEmpty()) if (!nameA.IsEmpty())
PrintPropPair(so, nameA, s); so << nameA;
else else
so << nameU << " = " << s << endl; so << nameU;
so << " = ";
PrintPropVal_MultiLine(so, s);
} }
} }
@@ -862,11 +919,11 @@ static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er)
{ {
PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags()); PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags());
if (!er.ErrorMessage.IsEmpty()) if (!er.ErrorMessage.IsEmpty())
PrintPropPair(so, "ERROR", er.ErrorMessage); PrintPropPair(so, "ERROR", er.ErrorMessage, true);
PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags()); PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags());
if (!er.WarningMessage.IsEmpty()) if (!er.WarningMessage.IsEmpty())
PrintPropPair(so, "WARNING", er.WarningMessage); PrintPropPair(so, "WARNING", er.WarningMessage, true);
} }
HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
@@ -877,7 +934,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
const CArcErrorInfo &er = arc.ErrorInfo; const CArcErrorInfo &er = arc.ErrorInfo;
so << "--\n"; so << "--\n";
PrintPropPair(so, "Path", arc.Path); PrintPropPair(so, "Path", arc.Path, false);
if (er.ErrorFormatIndex >= 0) if (er.ErrorFormatIndex >= 0)
{ {
if (er.ErrorFormatIndex == arc.FormatIndex) if (er.ErrorFormatIndex == arc.FormatIndex)
@@ -885,7 +942,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
else else
PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true); PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true);
} }
PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex)); PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false);
ErrorInfo_Print(so, er); ErrorInfo_Print(so, er);
@@ -943,7 +1000,8 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const
{ {
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
{ {
so << arcLink.NonOpen_ArcPath << endl; so.NormalizePrint_UString(arcLink.NonOpen_ArcPath);
so << endl;
PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
} }
else else
@@ -1014,15 +1072,18 @@ HRESULT ListArchives(CCodecs *codecs,
errorCode = ERROR_FILE_NOT_FOUND; errorCode = ERROR_FILE_NOT_FOUND;
lastError = HRESULT_FROM_WIN32(lastError);; lastError = HRESULT_FROM_WIN32(lastError);;
g_StdOut.Flush(); g_StdOut.Flush();
*g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl;
endl << arcPath << endl << endl; g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << endl << endl;
numErrors++; numErrors++;
continue; continue;
} }
if (fi.IsDir()) if (fi.IsDir())
{ {
g_StdOut.Flush(); g_StdOut.Flush();
*g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl; *g_ErrStream << endl << kError;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << " is not a file" << endl << endl;
numErrors++; numErrors++;
continue; continue;
} }
@@ -1061,7 +1122,9 @@ HRESULT ListArchives(CCodecs *codecs,
if (enableHeaders) if (enableHeaders)
{ {
g_StdOut << endl << kListing << arcPath << endl << endl; g_StdOut << endl << kListing;
g_StdOut.NormalizePrint_UString(arcPath);
g_StdOut << endl << endl;
} }
HRESULT result = arcLink.Open_Strict(options, &openCallback); HRESULT result = arcLink.Open_Strict(options, &openCallback);
@@ -1071,7 +1134,9 @@ HRESULT ListArchives(CCodecs *codecs,
if (result == E_ABORT) if (result == E_ABORT)
return result; return result;
g_StdOut.Flush(); g_StdOut.Flush();
*g_ErrStream << endl << kError << arcPath << " : "; *g_ErrStream << endl << kError;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << " : ";
if (result == S_FALSE) if (result == S_FALSE)
{ {
Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
@@ -1255,7 +1320,7 @@ HRESULT ListArchives(CCodecs *codecs,
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
{ {
g_StdOut << "----------\n"; g_StdOut << "----------\n";
PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath); PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false);
PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
} }
} }

View File

@@ -10,10 +10,6 @@
#include "../../../../C/CpuArch.h" #include "../../../../C/CpuArch.h"
#if defined( _7ZIP_LARGE_PAGES)
#include "../../../../C/Alloc.h"
#endif
#include "../../../Common/MyInitGuid.h" #include "../../../Common/MyInitGuid.h"
#include "../../../Common/CommandLineParser.h" #include "../../../Common/CommandLineParser.h"
@@ -25,10 +21,6 @@
#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/ErrorMsg.h"
#ifdef _WIN32
#include "../../../Windows/MemoryLock.h"
#endif
#include "../../../Windows/TimeUtils.h" #include "../../../Windows/TimeUtils.h"
#include "../Common/ArchiveCommandLine.h" #include "../Common/ArchiveCommandLine.h"
@@ -64,7 +56,7 @@ using namespace NCommandLineParser;
HINSTANCE g_hInstance = 0; HINSTANCE g_hInstance = 0;
#endif #endif
bool g_LargePagesMode = false; extern bool g_LargePagesMode;
extern CStdOutStream *g_StdStream; extern CStdOutStream *g_StdStream;
extern CStdOutStream *g_ErrStream; extern CStdOutStream *g_ErrStream;
@@ -244,7 +236,8 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so)
{ {
FOR_VECTOR(i, pc.Paths) FOR_VECTOR(i, pc.Paths)
{ {
so << pc.Paths[i] << " : "; so.NormalizePrint_UString(pc.Paths[i]);
so << " : ";
so << NError::MyFormatMessage(pc.Codes[i]) << endl; so << NError::MyFormatMessage(pc.Codes[i]) << endl;
} }
so << "----------------" << endl; so << "----------------" << endl;
@@ -383,6 +376,8 @@ static void PrintMemUsage(const char *s, UInt64 val)
*g_StdStream << " " << s << " Memory ="; *g_StdStream << " " << s << " Memory =";
PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
*g_StdStream << " MB"; *g_StdStream << " MB";
if (g_LargePagesMode)
*g_StdStream << " (LP)";
} }
EXTERN_C_BEGIN EXTERN_C_BEGIN
@@ -524,6 +519,8 @@ int Main2(
parser.Parse1(commandStrings, options); parser.Parse1(commandStrings, options);
g_StdOut.IsTerminalMode = options.IsStdOutTerminal;
g_StdErr.IsTerminalMode = options.IsStdErrTerminal;
if (options.Number_for_Out != k_OutStream_stdout) if (options.Number_for_Out != k_OutStream_stdout)
g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL);
@@ -541,24 +538,6 @@ int Main2(
return 0; return 0;
} }
#if defined(_WIN32) && !defined(UNDER_CE)
NSecurity::EnablePrivilege_SymLink();
#endif
#ifdef _7ZIP_LARGE_PAGES
if (options.LargePages)
{
SetLargePageSize();
// note: this process also can inherit that Privilege from parent process
g_LargePagesMode =
#if defined(_WIN32) && !defined(UNDER_CE)
NSecurity::EnablePrivilege_LockMemory();
#else
true;
#endif
}
#endif
if (options.EnableHeaders) if (options.EnableHeaders)
ShowCopyrightAndHelp(g_StdStream, false); ShowCopyrightAndHelp(g_StdStream, false);

View File

@@ -79,7 +79,7 @@ int MY_CDECL main
PrintError(kUserBreakMessage); PrintError(kUserBreakMessage);
return (NExitCode::kUserBreak); return (NExitCode::kUserBreak);
} }
catch(const CArcCmdLineException &e) catch(const CMessagePathException &e)
{ {
PrintError(kException_CmdLine_Error_Message); PrintError(kException_CmdLine_Error_Message);
if (g_ErrStream) if (g_ErrStream)

View File

@@ -141,8 +141,9 @@ void CPercentPrinter::Print()
{ {
_s += ' '; _s += ' ';
StdOut_Convert_UString_to_AString(FileName, _temp); _tempU = FileName;
_temp.Replace('\n', ' '); _so->Normalize_UString(_tempU);
StdOut_Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() > MaxLen) if (_s.Len() + _temp.Len() > MaxLen)
{ {
unsigned len = FileName.Len(); unsigned len = FileName.Len();
@@ -153,8 +154,9 @@ void CPercentPrinter::Print()
delta = 1; delta = 1;
len -= delta; len -= delta;
_tempU = FileName; _tempU = FileName;
_tempU.Delete(len / 2, FileName.Len() - len); _tempU.Delete(len / 2, _tempU.Len() - len);
_tempU.Insert(len / 2, L" . "); _tempU.Insert(len / 2, L" . ");
_so->Normalize_UString(_tempU);
StdOut_Convert_UString_to_AString(_tempU, _temp); StdOut_Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() <= MaxLen) if (_s.Len() + _temp.Len() <= MaxLen)
break; break;

View File

@@ -143,7 +143,9 @@ HRESULT CUpdateCallbackConsole::OpenResult(
_so->Flush(); _so->Flush();
if (_se) if (_se)
{ {
*_se << kError << name << endl; *_se << kError;
_se->NormalizePrint_wstr(name);
*_se << endl;
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
RINOK(res); RINOK(res);
_se->Flush(); _se->Flush();
@@ -185,7 +187,9 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b
*_se << endl << (isWarning ? kWarning : kError) *_se << endl << (isWarning ? kWarning : kError)
<< NError::MyFormatMessage(systemError) << NError::MyFormatMessage(systemError)
<< endl << fs2us(path) << endl << endl; << endl;
_se->NormalizePrint_UString(fs2us(path));
*_se << endl << endl;
_se->Flush(); _se->Flush();
} }
} }
@@ -281,8 +285,8 @@ HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
if (_so) if (_so)
{ {
*_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);
if (name != 0) if (name)
*_so << name; _so->NormalizePrint_wstr(name);
else else
*_so << k_StdOut_ArcName; *_so << k_StdOut_ArcName;
*_so << endl << endl; *_so << endl << endl;
@@ -343,6 +347,7 @@ HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool
_tempA.Add_Space(); _tempA.Add_Space();
*_so << _tempA; *_so << _tempA;
_tempU = fs2us(path); _tempU = fs2us(path);
_so->Normalize_UString(_tempU);
_so->PrintUString(_tempU, _tempA); _so->PrintUString(_tempU, _tempA);
*_so << endl; *_so << endl;
if (NeedFlush) if (NeedFlush)
@@ -475,7 +480,10 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com
_tempU.Empty(); _tempU.Empty();
if (name) if (name)
{
_tempU = name; _tempU = name;
_so->Normalize_UString(_tempU);
}
_so->PrintUString(_tempU, _tempA); _so->PrintUString(_tempU, _tempA);
*_so << endl; *_so << endl;
if (NeedFlush) if (NeedFlush)
@@ -568,7 +576,9 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt
AString s; AString s;
SetExtractErrorMessage(opRes, isEncrypted, s); SetExtractErrorMessage(opRes, isEncrypted, s);
*_se << s << " : " << endl << name << endl << endl; *_se << s << " : " << endl;
_se->NormalizePrint_wstr(name);
*_se << endl << endl;
_se->Flush(); _se->Flush();
} }
return S_OK; return S_OK;

View File

@@ -1,3 +1,7 @@
#include "../../MyVersionInfo.rc" #include "../../MyVersionInfo.rc"
MY_VERSION_INFO_APP("7-Zip Console" , "7z") MY_VERSION_INFO_APP("7-Zip Console" , "7z")
#ifndef UNDER_CE
1 24 MOVEABLE PURE "Console.manifest"
#endif

View File

@@ -479,6 +479,14 @@ SOURCE=..\..\..\Windows\MemoryGlobal.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\MemoryLock.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\MemoryLock.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Menu.cpp SOURCE=..\..\..\Windows\Menu.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -34,6 +34,7 @@ WIN_OBJS = \
$O\FileFind.obj \ $O\FileFind.obj \
$O\FileIO.obj \ $O\FileIO.obj \
$O\FileName.obj \ $O\FileName.obj \
$O\MemoryLock.obj \
$O\Menu.obj \ $O\Menu.obj \
$O\ProcessUtils.obj \ $O\ProcessUtils.obj \
$O\Registry.obj \ $O\Registry.obj \

View File

@@ -209,6 +209,8 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s)
s = "Is not archive"; s = "Is not archive";
else if (opRes == NArchive::NExtract::NOperationResult::kHeadersError) else if (opRes == NArchive::NExtract::NOperationResult::kHeadersError)
s = "kHeaders Error"; s = "kHeaders Error";
else if (opRes == NArchive::NExtract::NOperationResult::kWrongPassword)
s = "Wrong Password";
else else
{ {
s = "Error #"; s = "Error #";

View File

@@ -5,6 +5,13 @@
<dependency> <dependency>
<dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly>
</dependency> </dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
<asmv3:application> <asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware> <dpiAware>true</dpiAware>

View File

@@ -0,0 +1,57 @@
// EditDialog.cpp
#include "StdAfx.h"
#include "EditDialog.h"
#ifdef LANG
#include "LangUtils.h"
#endif
bool CEditDialog::OnInit()
{
#ifdef LANG
LangSetDlgItems(*this, NULL, 0);
#endif
_edit.Attach(GetItem(IDE_EDIT));
SetText(Title);
_edit.SetText(Text);
NormalizeSize();
return CModalDialog::OnInit();
}
// #define MY_CLOSE_BUTTON__ID IDCANCEL
#define MY_CLOSE_BUTTON__ID IDCLOSE
bool CEditDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
{
int mx, my;
GetMargins(8, mx, my);
int bx1, by;
GetItemSizes(MY_CLOSE_BUTTON__ID, bx1, by);
// int bx2;
// GetItemSizes(IDOK, bx2, by);
int y = ySize - my - by;
int x = xSize - mx - bx1;
/*
RECT rect;
GetClientRect(&rect);
rect.top = y - my;
InvalidateRect(&rect);
*/
InvalidateRect(NULL);
MoveItem(MY_CLOSE_BUTTON__ID, x, y, bx1, by);
// MoveItem(IDOK, x - mx - bx2, y, bx2, by);
/*
if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE)
mx = 0;
*/
_edit.Move(mx, my, xSize - mx * 2, y - my * 2);
return false;
}

View File

@@ -0,0 +1,25 @@
// EditDialog.h
#ifndef __EDIT_DIALOG_H
#define __EDIT_DIALOG_H
#include "../../../Windows/Control/Dialog.h"
#include "../../../Windows/Control/Edit.h"
#include "EditDialogRes.h"
class CEditDialog: public NWindows::NControl::CModalDialog
{
NWindows::NControl::CEdit _edit;
virtual bool OnInit();
virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
public:
UString Title;
UString Text;
INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_EDIT_DLG, wndParent); }
CEditDialog() {}
};
#endif

View File

@@ -0,0 +1,15 @@
#include "EditDialogRes.h"
#include "../../GuiCommon.rc"
#define xc 320
#define yc 240
IDD_EDIT_DLG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
CAPTION "Edit"
{
// OK_CANCEL
MY_BUTTON__CLOSE
EDITTEXT IDE_EDIT, m, m, xc, yc - bys - m,
ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | ES_WANTRETURN
}

View File

@@ -0,0 +1,2 @@
#define IDD_EDIT_DLG 94
#define IDE_EDIT 100

View File

@@ -383,6 +383,7 @@ static void SetMemoryLock()
NSecurity::AddLockMemoryPrivilege(); NSecurity::AddLockMemoryPrivilege();
if (ReadLockMemoryEnable()) if (ReadLockMemoryEnable())
if (NSecurity::Get_LargePages_RiskLevel() == 0)
{ {
// note: child processes can inherit that Privilege // note: child processes can inherit that Privilege
g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory(); g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory();

View File

@@ -491,6 +491,14 @@ SOURCE=.\DialogSize.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\EditDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\EditDialog.h
# End Source File
# Begin Source File
SOURCE=.\LinkDialog.cpp SOURCE=.\LinkDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -46,6 +46,7 @@ FM_OBJS = \
$O\AboutDialog.obj \ $O\AboutDialog.obj \
$O\ComboDialog.obj \ $O\ComboDialog.obj \
$O\CopyDialog.obj \ $O\CopyDialog.obj \
$O\EditDialog.obj \
$O\EditPage.obj \ $O\EditPage.obj \
$O\LangPage.obj \ $O\LangPage.obj \
$O\ListViewDialog.obj \ $O\ListViewDialog.obj \

View File

@@ -58,6 +58,7 @@ static const CIDLangPair kLangPairs[] =
{ IDCANCEL, 402 }, { IDCANCEL, 402 },
{ IDYES, 406 }, { IDYES, 406 },
{ IDNO, 407 }, { IDNO, 407 },
{ IDCLOSE, 408 },
{ IDHELP, 409 } { IDHELP, 409 }
}; };

View File

@@ -2,6 +2,9 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../Windows/Clipboard.h"
#include "EditDialog.h"
#include "ListViewDialog.h" #include "ListViewDialog.h"
#include "RegistryUtils.h" #include "RegistryUtils.h"
@@ -11,6 +14,23 @@
using namespace NWindows; using namespace NWindows;
static const unsigned kOneStringMaxSize = 1024;
static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector)
{
vector.Clear();
int index = -1;
for (;;)
{
index = listView.GetNextSelectedItem(index);
if (index < 0)
break;
vector.Add(index);
}
}
bool CListViewDialog::OnInit() bool CListViewDialog::OnInit()
{ {
#ifdef LANG #ifdef LANG
@@ -18,28 +38,92 @@ bool CListViewDialog::OnInit()
#endif #endif
_listView.Attach(GetItem(IDL_LISTVIEW)); _listView.Attach(GetItem(IDL_LISTVIEW));
if (NumColumns > 1)
{
LONG_PTR style = _listView.GetStyle();
style &= ~(LONG_PTR)LVS_NOCOLUMNHEADER;
_listView.SetStyle(style);
}
CFmSettings st; CFmSettings st;
st.Load(); st.Load();
DWORD exStyle = 0;
if (st.SingleClick) if (st.SingleClick)
_listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT); exStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
exStyle |= LVS_EX_FULLROWSELECT;
if (exStyle != 0)
_listView.SetExtendedListViewStyle(exStyle);
SetText(Title); SetText(Title);
const int kWidth = 400;
LVCOLUMN columnInfo; LVCOLUMN columnInfo;
columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
columnInfo.fmt = LVCFMT_LEFT; columnInfo.fmt = LVCFMT_LEFT;
columnInfo.iSubItem = 0; columnInfo.iSubItem = 0;
columnInfo.cx = 200; columnInfo.cx = kWidth;
columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Property"
if (NumColumns > 1)
{
columnInfo.cx = 100;
/*
// Windows always uses LVCFMT_LEFT for first column.
// if we need LVCFMT_RIGHT, we can create dummy column and then remove it
// columnInfo.mask |= LVCF_TEXT;
_listView.InsertColumn(0, &columnInfo); _listView.InsertColumn(0, &columnInfo);
columnInfo.iSubItem = 1;
columnInfo.fmt = LVCFMT_RIGHT;
_listView.InsertColumn(1, &columnInfo);
_listView.DeleteColumn(0);
*/
}
// else
_listView.InsertColumn(0, &columnInfo);
if (NumColumns > 1)
{
// columnInfo.fmt = LVCFMT_LEFT;
columnInfo.cx = kWidth - columnInfo.cx;
columnInfo.iSubItem = 1;
// columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Value"
_listView.InsertColumn(1, &columnInfo);
}
UString s;
FOR_VECTOR (i, Strings) FOR_VECTOR (i, Strings)
{
_listView.InsertItem(i, Strings[i]); _listView.InsertItem(i, Strings[i]);
if (Strings.Size() > 0) if (NumColumns > 1 && i < Values.Size())
{
s = Values[i];
if (s.Len() > kOneStringMaxSize)
{
s.DeleteFrom(kOneStringMaxSize);
s += " ...";
}
s.Replace(L"\r\n", L" ");
s.Replace(L"\n", L" ");
_listView.SetSubItem(i, 1, s);
}
}
if (SelectFirst && Strings.Size() > 0)
_listView.SetItemState_FocusedSelected(0); _listView.SetItemState_FocusedSelected(0);
_listView.SetColumnWidthAuto(0); _listView.SetColumnWidthAuto(0);
if (NumColumns > 1)
_listView.SetColumnWidthAuto(1);
StringsWereChanged = false; StringsWereChanged = false;
NormalizeSize(); NormalizeSize();
@@ -74,8 +158,97 @@ bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
return false; return false;
} }
extern bool g_LVN_ITEMACTIVATE_Support; extern bool g_LVN_ITEMACTIVATE_Support;
void CListViewDialog::CopyToClipboard()
{
CUIntVector indexes;
ListView_GetSelected(_listView, indexes);
UString s;
FOR_VECTOR (i, indexes)
{
unsigned index = indexes[i];
s += Strings[index];
if (NumColumns > 1 && index < Values.Size())
{
const UString &v = Values[index];
// if (!v.IsEmpty())
{
s += ": ";
s += v;
}
}
// if (indexes.Size() > 1)
{
s +=
#ifdef _WIN32
"\r\n"
#else
"\n"
#endif
;
}
}
ClipboardSetText(*this, s);
}
void CListViewDialog::ShowItemInfo()
{
CUIntVector indexes;
ListView_GetSelected(_listView, indexes);
if (indexes.Size() != 1)
return;
unsigned index = indexes[0];
CEditDialog dlg;
if (NumColumns == 1)
dlg.Text = Strings[index];
else
{
dlg.Title = Strings[index];
if (index < Values.Size())
dlg.Text = Values[index];
}
dlg.Create(*this);
}
void CListViewDialog::DeleteItems()
{
for (;;)
{
int index = _listView.GetNextSelectedItem(-1);
if (index < 0)
break;
StringsWereChanged = true;
_listView.DeleteItem(index);
if ((unsigned)index < Strings.Size())
Strings.Delete(index);
if ((unsigned)index < Values.Size())
Values.Delete(index);
}
int focusedIndex = _listView.GetFocusedItem();
if (focusedIndex >= 0)
_listView.SetItemState_FocusedSelected(focusedIndex);
_listView.SetColumnWidthAuto(0);
}
void CListViewDialog::OnEnter()
{
if (IsKeyDown(VK_MENU)
|| NumColumns > 1)
{
ShowItemInfo();
return;
}
OnOK();
}
bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{ {
if (header->hwndFrom != _listView) if (header->hwndFrom != _listView)
@@ -85,7 +258,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
case LVN_ITEMACTIVATE: case LVN_ITEMACTIVATE:
if (g_LVN_ITEMACTIVATE_Support) if (g_LVN_ITEMACTIVATE_Support)
{ {
OnOK(); OnEnter();
return true; return true;
} }
break; break;
@@ -93,7 +266,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
case NM_RETURN: // probabably it's unused case NM_RETURN: // probabably it's unused
if (!g_LVN_ITEMACTIVATE_Support) if (!g_LVN_ITEMACTIVATE_Support)
{ {
OnOK(); OnEnter();
return true; return true;
} }
break; break;
@@ -107,19 +280,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{ {
if (!DeleteIsAllowed) if (!DeleteIsAllowed)
return false; return false;
for (;;) DeleteItems();
{
int index = _listView.GetNextSelectedItem(-1);
if (index < 0)
break;
StringsWereChanged = true;
_listView.DeleteItem(index);
Strings.Delete(index);
}
int focusedIndex = _listView.GetFocusedItem();
if (focusedIndex >= 0)
_listView.SetItemState_FocusedSelected(focusedIndex);
_listView.SetColumnWidthAuto(0);
return true; return true;
} }
case 'A': case 'A':
@@ -129,6 +290,17 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
_listView.SelectAll(); _listView.SelectAll();
return true; return true;
} }
break;
}
case VK_INSERT:
case 'C':
{
if (IsKeyDown(VK_CONTROL))
{
CopyToClipboard();
return true;
}
break;
} }
} }
} }

View File

@@ -15,16 +15,32 @@ class CListViewDialog: public NWindows::NControl::CModalDialog
virtual bool OnInit(); virtual bool OnInit();
virtual bool OnSize(WPARAM wParam, int xSize, int ySize); virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
virtual bool OnNotify(UINT controlID, LPNMHDR header); virtual bool OnNotify(UINT controlID, LPNMHDR header);
void CopyToClipboard();
void DeleteItems();
void ShowItemInfo();
void OnEnter();
public: public:
UString Title; UString Title;
bool SelectFirst;
bool DeleteIsAllowed; bool DeleteIsAllowed;
bool StringsWereChanged; bool StringsWereChanged;
UStringVector Strings; UStringVector Strings;
UStringVector Values;
int FocusedItemIndex; int FocusedItemIndex;
unsigned NumColumns;
INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); } INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); }
CListViewDialog(): DeleteIsAllowed(false) {} CListViewDialog():
SelectFirst(false),
DeleteIsAllowed(false),
StringsWereChanged(false),
FocusedItemIndex(-1),
NumColumns(1)
{}
}; };
#endif #endif

View File

@@ -1,8 +1,8 @@
#include "ListViewDialogRes.h" #include "ListViewDialogRes.h"
#include "../../GuiCommon.rc" #include "../../GuiCommon.rc"
#define xc 320 #define xc 440
#define yc 240 #define yc 320
IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
CAPTION "ListView" CAPTION "ListView"

View File

@@ -16,7 +16,11 @@ using namespace NWindows;
class CPanelCopyThread: public CProgressThreadVirt class CPanelCopyThread: public CProgressThreadVirt
{ {
bool ResultsWereShown;
bool NeedShowRes;
HRESULT ProcessVirt(); HRESULT ProcessVirt();
virtual void ProcessWasFinished_GuiVirt();
public: public:
const CCopyToOptions *options; const CCopyToOptions *options;
CMyComPtr<IFolderOperations> FolderOperations; CMyComPtr<IFolderOperations> FolderOperations;
@@ -29,10 +33,30 @@ public:
HRESULT Result; HRESULT Result;
void ShowFinalResults(HWND hwnd);
CPanelCopyThread(): Result(E_FAIL) {} CPanelCopyThread():
Result(E_FAIL),
ResultsWereShown(false),
NeedShowRes(false)
{}
}; };
void CPanelCopyThread::ShowFinalResults(HWND hwnd)
{
if (NeedShowRes)
if (!ResultsWereShown)
{
ResultsWereShown = true;
ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
}
}
void CPanelCopyThread::ProcessWasFinished_GuiVirt()
{
ShowFinalResults(*this);
}
HRESULT CPanelCopyThread::ProcessVirt() HRESULT CPanelCopyThread::ProcessVirt()
{ {
/* /*
@@ -69,12 +93,16 @@ HRESULT CPanelCopyThread::ProcessVirt()
BoolToInt(options->replaceAltStreamChars), BoolToInt(options->replaceAltStreamChars),
options->folder, ExtractCallback); options->folder, ExtractCallback);
if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors && if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors)
(!options->hashMethods.IsEmpty() || options->testMode)) {
if (!options->hashMethods.IsEmpty())
NeedShowRes = true;
else if (options->testMode)
{ {
CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0); CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
AddHashBundleRes(pair.Message, Hash, FirstFilePath); AddHashBundleRes(pair.Message, Hash, FirstFilePath);
} }
}
return Result; return Result;
} }
@@ -92,7 +120,6 @@ static void ThrowException_if_Error(HRESULT res)
#endif #endif
*/ */
HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices, HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices,
UStringVector *messages, UStringVector *messages,
bool &usePassword, UString &password) bool &usePassword, UString &password)
@@ -102,7 +129,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (options.showErrorMessages) if (options.showErrorMessages)
MessageBox_Error(errorMessage); MessageBox_Error(errorMessage);
else if (messages != 0) else if (messages)
messages->Add(errorMessage); messages->Add(errorMessage);
return E_FAIL; return E_FAIL;
} }
@@ -124,8 +151,8 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.ExtractCallback = extracter.ExtractCallbackSpec; extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.options = &options; extracter.options = &options;
extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
extracter.ProgressDialog.CompressingMode = false; extracter.CompressingMode = false;
extracter.ExtractCallbackSpec->StreamMode = options.streamMode; extracter.ExtractCallbackSpec->StreamMode = options.streamMode;
@@ -185,9 +212,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE); UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
extracter.ProgressDialog.MainWindow = GetParent(); extracter.MainWindow = GetParent();
extracter.ProgressDialog.MainTitle = progressWindowTitle; extracter.MainTitle = progressWindowTitle;
extracter.ProgressDialog.MainAddTitle = title + L' '; extracter.MainAddTitle = title + L' ';
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk; extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk;
extracter.ExtractCallbackSpec->Init(); extracter.ExtractCallbackSpec->Init();
@@ -199,8 +226,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
RINOK(extracter.Create(title, GetParent())); RINOK(extracter.Create(title, GetParent()));
if (messages != 0)
*messages = extracter.ProgressDialog.Sync.Messages; if (messages)
*messages = extracter.Sync.Messages;
res = extracter.Result; res = extracter.Result;
if (res == S_OK && extracter.ExtractCallbackSpec->IsOK()) if (res == S_OK && extracter.ExtractCallbackSpec->IsOK())
@@ -208,6 +236,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined; usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined;
password = extracter.ExtractCallbackSpec->Password; password = extracter.ExtractCallbackSpec->Password;
} }
extracter.ShowFinalResults(_window);
} }
RefreshTitleAlways(); RefreshTitleAlways();
@@ -297,7 +328,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater)); RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater));
updater.ProgressDialog.Create(title, thread, GetParent()); updater.ProgressDialog.Create(title, thread, GetParent());
if (messages != 0) if (messages)
*messages = updater.ProgressDialog.Sync.Messages; *messages = updater.ProgressDialog.Sync.Messages;
res = updater.Result; res = updater.Result;
@@ -308,7 +339,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (showErrorMessages) if (showErrorMessages)
MessageBox_Error(errorMessage); MessageBox_Error(errorMessage);
else if (messages != 0) else if (messages)
messages->Add(errorMessage); messages->Add(errorMessage);
return E_ABORT; return E_ABORT;
} }

View File

@@ -139,18 +139,44 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
class CThreadCrc: public CProgressThreadVirt class CThreadCrc: public CProgressThreadVirt
{ {
bool ResultsWereShown;
bool WasFinished;
HRESULT ProcessVirt(); HRESULT ProcessVirt();
virtual void ProcessWasFinished_GuiVirt();
public: public:
CDirEnumerator Enumerator; CDirEnumerator Enumerator;
CHashBundle Hash; CHashBundle Hash;
FString FirstFilePath;
void SetStatus(const UString &s); void SetStatus(const UString &s);
void AddErrorMessage(DWORD systemError, const FChar *name); void AddErrorMessage(DWORD systemError, const FChar *name);
void ShowFinalResults(HWND hwnd);
CThreadCrc():
ResultsWereShown(false),
WasFinished(false)
{}
}; };
void CThreadCrc::ShowFinalResults(HWND hwnd)
{
if (WasFinished)
if (!ResultsWereShown)
{
ResultsWereShown = true;
ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
}
}
void CThreadCrc::ProcessWasFinished_GuiVirt()
{
ShowFinalResults(*this);
}
void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name) void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name)
{ {
ProgressDialog.Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name)); Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name));
Hash.NumErrors++; Hash.NumErrors++;
} }
@@ -162,7 +188,7 @@ void CThreadCrc::SetStatus(const UString &s2)
s.Add_Space_if_NotEmpty(); s.Add_Space_if_NotEmpty();
s += fs2us(Enumerator.BasePrefix); s += fs2us(Enumerator.BasePrefix);
} }
ProgressDialog.Sync.Set_Status(s); Sync.Set_Status(s);
} }
HRESULT CThreadCrc::ProcessVirt() HRESULT CThreadCrc::ProcessVirt()
@@ -173,7 +199,7 @@ HRESULT CThreadCrc::ProcessVirt()
if (!buf.Allocate(kBufSize)) if (!buf.Allocate(kBufSize))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
CProgressSync &sync = ProgressDialog.Sync; CProgressSync &sync = Sync;
SetStatus(LangString(IDS_SCANNING)); SetStatus(LangString(IDS_SCANNING));
@@ -233,7 +259,6 @@ HRESULT CThreadCrc::ProcessVirt()
Enumerator.Init(); Enumerator.Init();
FString tempPath; FString tempPath;
FString firstFilePath;
bool isFirstFile = true; bool isFirstFile = true;
UInt64 errorsFilesSize = 0; UInt64 errorsFilesSize = 0;
@@ -264,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt()
} }
if (isFirstFile) if (isFirstFile)
{ {
firstFilePath = path; FirstFilePath = path;
isFirstFile = false; isFirstFile = false;
} }
sync.Set_FilePath(fs2us(path)); sync.Set_FilePath(fs2us(path));
@@ -303,12 +328,13 @@ HRESULT CThreadCrc::ProcessVirt()
SetStatus(L""); SetStatus(L"");
CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0); CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0);
AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath)); WasFinished = true;
LangString(IDS_CHECKSUM_INFORMATION, pair.Title); LangString(IDS_CHECKSUM_INFORMATION, pair.Title);
return S_OK; return S_OK;
} }
HRESULT CApp::CalculateCrc2(const UString &methodName) HRESULT CApp::CalculateCrc2(const UString &methodName)
{ {
unsigned srcPanelIndex = GetFocusedPanelIndex(); unsigned srcPanelIndex = GetFocusedPanelIndex();
@@ -338,6 +364,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
{ {
CThreadCrc t; CThreadCrc t;
{ {
UStringVector methods; UStringVector methods;
methods.Add(methodName); methods.Add(methodName);
@@ -360,17 +387,20 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
t.Enumerator.EnterToDirs = !GetFlatMode(); t.Enumerator.EnterToDirs = !GetFlatMode();
t.ProgressDialog.ShowCompressionInfo = false; t.ShowCompressionInfo = false;
UString title = LangString(IDS_CHECKSUM_CALCULATING); UString title = LangString(IDS_CHECKSUM_CALCULATING);
t.ProgressDialog.MainWindow = _window; t.MainWindow = _window;
t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.ProgressDialog.MainAddTitle = title; t.MainAddTitle = title;
t.ProgressDialog.MainAddTitle.Add_Space(); t.MainAddTitle.Add_Space();
RINOK(t.Create(title, _window)); RINOK(t.Create(title, _window));
t.ShowFinalResults(_window);
} }
RefreshTitleAlways(); RefreshTitleAlways();
return S_OK; return S_OK;
} }

View File

@@ -81,15 +81,17 @@ CDataObject::CDataObject()
STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */) STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */)
{ {
if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL && if (etc->cfFormat == m_SetFolderFormat
etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL) && etc->tymed == TYMED_HGLOBAL
&& etc->dwAspect == DVASPECT_CONTENT
&& medium->tymed == TYMED_HGLOBAL)
{ {
Path.Empty(); Path.Empty();
if (medium->hGlobal == 0) if (!medium->hGlobal)
return S_OK; return S_OK;
size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t); size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t);
const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal); const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal);
if (src != 0) if (src)
{ {
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
{ {
@@ -109,13 +111,13 @@ static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal)
{ {
SIZE_T size = GlobalSize(srcGlobal); SIZE_T size = GlobalSize(srcGlobal);
const void *src = GlobalLock(srcGlobal); const void *src = GlobalLock(srcGlobal);
if (src == 0) if (!src)
return 0; return 0;
HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size);
if (destGlobal != 0) if (destGlobal)
{ {
void *dest = GlobalLock(destGlobal); void *dest = GlobalLock(destGlobal);
if (dest == 0) if (!dest)
{ {
GlobalFree(destGlobal); GlobalFree(destGlobal);
destGlobal = 0; destGlobal = 0;
@@ -136,7 +138,7 @@ STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium)
medium->tymed = m_Etc.tymed; medium->tymed = m_Etc.tymed;
medium->pUnkForRelease = 0; medium->pUnkForRelease = 0;
medium->hGlobal = DuplicateGlobalMem(hGlobal); medium->hGlobal = DuplicateGlobalMem(hGlobal);
if (medium->hGlobal == 0) if (!medium->hGlobal)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
return S_OK; return S_OK;
} }
@@ -261,7 +263,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
NMemory::CGlobalLock dropLock(hgDrop); NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0) if (!dropFiles)
return false; return false;
dropFiles->fNC = FALSE; dropFiles->fNC = FALSE;
dropFiles->pt.x = 0; dropFiles->pt.x = 0;
@@ -291,7 +293,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
NMemory::CGlobalLock dropLock(hgDrop); NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0) if (!dropFiles)
return false; return false;
dropFiles->fNC = FALSE; dropFiles->fNC = FALSE;
dropFiles->pt.x = 0; dropFiles->pt.x = 0;
@@ -336,7 +338,11 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dirPrefix = us2fs(GetFsPath()); dirPrefix = us2fs(GetFsPath());
else else
{ {
tempDirectory.Create(kTempDirPrefix); if (!tempDirectory.Create(kTempDirPrefix))
{
MessageBox_Error(L"Can't create temp folder");
return;
}
dirPrefix = tempDirectory.GetPath(); dirPrefix = tempDirectory.GetPath();
// dirPrefix2 = dirPrefix; // dirPrefix2 = dirPrefix;
NFile::NName::NormalizeDirPathPrefix(dirPrefix); NFile::NName::NormalizeDirPathPrefix(dirPrefix);
@@ -394,11 +400,67 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dropSourceSpec->DataObjectSpec = dataObjectSpec; dropSourceSpec->DataObjectSpec = dataObjectSpec;
dropSourceSpec->DataObject = dataObjectSpec; dropSourceSpec->DataObject = dataObjectSpec;
bool moveIsAllowed = isFSFolder;
/*
CTime - file creation timestamp.
There are two operations in Windows with Drag and Drop:
COPY_OPERATION - icon with Plus sign - CTime will be set as current_time.
MOVE_OPERATION - icon without Plus sign - CTime will be preserved
Note: if we call DoDragDrop() with (effectsOK = DROPEFFECT_MOVE), then
it will use MOVE_OPERATION and CTime will be preserved.
But MoveFile() function doesn't preserve CTime, if different volumes are used.
Why it's so?
Does DoDragDrop() use some another function (not MoveFile())?
if (effectsOK == DROPEFFECT_COPY) it works as COPY_OPERATION
if (effectsOK == DROPEFFECT_MOVE) drag works as MOVE_OPERATION
if (effectsOK == (DROPEFFECT_COPY | DROPEFFECT_MOVE))
{
if we drag file to same volume, then Windows suggests:
CTRL - COPY_OPERATION
[default] - MOVE_OPERATION
if we drag file to another volume, then Windows suggests
[default] - COPY_OPERATION
SHIFT - MOVE_OPERATION
}
We want to use MOVE_OPERATION for extracting from archive (open in 7-Zip) to Explorer:
It has the following advantages:
1) it uses fast MOVE_OPERATION instead of slow COPY_OPERATION and DELETE, if same volume.
2) it preserved CTime
Some another programs support only COPY_OPERATION.
So we can use (DROPEFFECT_COPY | DROPEFFECT_MOVE)
Also another program can return from DoDragDrop() before
files using. But we delete temp folder after DoDragDrop(),
and another program can't open input files in that case.
We create objects:
IDropSource *dropSource
IDataObject *dataObject
if DropTarget is 7-Zip window, then 7-Zip's
IDropTarget::DragOver() sets Path in IDataObject.
and
IDropSource::QueryContinueDrag() sets NeedPostCopy, if Path is not epmty.
So we can detect destination path after DoDragDrop().
Now we don't know any good way to detect destination path for D&D to Explorer.
*/
bool moveIsAllowed = isFSFolder;
/*
DWORD effectsOK = DROPEFFECT_COPY; DWORD effectsOK = DROPEFFECT_COPY;
if (moveIsAllowed) if (moveIsAllowed)
effectsOK |= DROPEFFECT_MOVE; effectsOK |= DROPEFFECT_MOVE;
*/
// 18.04: was changed
DWORD effectsOK = DROPEFFECT_MOVE | DROPEFFECT_COPY;
DWORD effect; DWORD effect;
_panelCallback->DragBegin(); _panelCallback->DragBegin();
@@ -418,7 +480,8 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path); NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path);
CCopyToOptions options; CCopyToOptions options;
options.folder = dataObjectSpec->Path; options.folder = dataObjectSpec->Path;
options.moveMode = (effect == DROPEFFECT_MOVE); // if MOVE is not allowed, we just use COPY operation
options.moveMode = (effect == DROPEFFECT_MOVE && moveIsAllowed);
res = CopyTo(options, indices, &dropSourceSpec->Messages); res = CopyTo(options, indices, &dropSourceSpec->Messages);
} }
/* /*
@@ -475,7 +538,7 @@ static void MySetDropHighlighted(HWND hWnd, int index, bool enable)
void CDropTarget::RemoveSelection() void CDropTarget::RemoveSelection()
{ {
if (m_SelectionIndex >= 0 && m_Panel != 0) if (m_SelectionIndex >= 0 && m_Panel)
MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false); MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false);
m_SelectionIndex = -1; m_SelectionIndex = -1;
} }
@@ -555,7 +618,7 @@ void CDropTarget::PositionCursor(POINTL ptl)
bool CDropTarget::IsFsFolderPath() const bool CDropTarget::IsFsFolderPath() const
{ {
if (!m_IsAppTarget && m_Panel != 0) if (!m_IsAppTarget && m_Panel)
return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0)); return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0));
return false; return false;
} }
@@ -614,7 +677,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names
size_t blockSize = GlobalSize(medium.hGlobal); size_t blockSize = GlobalSize(medium.hGlobal);
NMemory::CGlobalLock dropLock(medium.hGlobal); NMemory::CGlobalLock dropLock(medium.hGlobal);
const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0) if (!dropFiles)
return; return;
if (blockSize < dropFiles->pFiles) if (blockSize < dropFiles->pFiles)
return; return;
@@ -629,7 +692,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names
bool CDropTarget::IsItSameDrive() const bool CDropTarget::IsItSameDrive() const
{ {
if (m_Panel == 0) if (!m_Panel)
return false; return false;
if (!IsFsFolderPath()) if (!IsFsFolderPath())
return false; return false;
@@ -662,6 +725,21 @@ bool CDropTarget::IsItSameDrive() const
return true; return true;
} }
/*
There are 2 different actions, when we drag to 7-Zip:
1) Drag from any external program except of Explorer to "7-Zip" FS folder.
We want to create new archive for that operation.
2) all another operation work as usual file COPY/MOVE
- Drag from "7-Zip" FS to "7-Zip" FS.
COPY/MOVE are supported.
- Drag to open archive in 7-Zip.
We want to update archive.
We replace COPY to MOVE.
- Drag from "7-Zip" archive to "7-Zip" FS.
We replace COPY to MOVE.
*/
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect) DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect)
{ {
if (!m_DropIsAllowed || !m_PanelDropIsAllowed) if (!m_DropIsAllowed || !m_PanelDropIsAllowed)
@@ -671,10 +749,12 @@ DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffec
allowedEffect &= ~DROPEFFECT_MOVE; allowedEffect &= ~DROPEFFECT_MOVE;
DWORD effect = 0; DWORD effect = 0;
if (keyState & MK_CONTROL) if (keyState & MK_CONTROL)
effect = allowedEffect & DROPEFFECT_COPY; effect = allowedEffect & DROPEFFECT_COPY;
else if (keyState & MK_SHIFT) else if (keyState & MK_SHIFT)
effect = allowedEffect & DROPEFFECT_MOVE; effect = allowedEffect & DROPEFFECT_MOVE;
if (effect == 0) if (effect == 0)
{ {
if (allowedEffect & DROPEFFECT_COPY) if (allowedEffect & DROPEFFECT_COPY)
@@ -716,10 +796,10 @@ bool CDropTarget::SetPath(bool enablePath) const
path = GetTargetPath(); path = GetTargetPath();
size_t size = path.Len() + 1; size_t size = path.Len() + 1;
medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t)); medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t));
if (medium.hGlobal == 0) if (!medium.hGlobal)
return false; return false;
wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal); wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal);
if (dest == 0) if (!dest)
{ {
GlobalUnlock(medium.hGlobal); GlobalUnlock(medium.hGlobal);
return false; return false;

View File

@@ -625,6 +625,7 @@ void CPanel::FoldersHistory()
{ {
CListViewDialog listViewDialog; CListViewDialog listViewDialog;
listViewDialog.DeleteIsAllowed = true; listViewDialog.DeleteIsAllowed = true;
listViewDialog.SelectFirst = true;
LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title); LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title);
_appState->FolderHistory.GetList(listViewDialog.Strings); _appState->FolderHistory.GetList(listViewDialog.Strings);
if (listViewDialog.Create(GetParent()) != IDOK) if (listViewDialog.Create(GetParent()) != IDOK)

View File

@@ -674,7 +674,7 @@ static const char * const kStartExtensions =
#endif #endif
" exe bat ps1 com" " exe bat ps1 com"
" chm" " chm"
" msi doc xls ppt pps wps wpt wks xlr wdb vsd pub" " msi doc dot xls ppt pps wps wpt wks xlr wdb vsd pub"
" docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps" " docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps"
" xlam pptx pptm potx potm ppam ppsx ppsm xsn" " xlam pptx pptm potx potm ppam ppsx ppsm xsn"
@@ -1151,7 +1151,7 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
CThreadCopyFrom t; CThreadCopyFrom t;
t.UpdateCallbackSpec = new CUpdateCallback100Imp; t.UpdateCallbackSpec = new CUpdateCallback100Imp;
t.UpdateCallback = t.UpdateCallbackSpec; t.UpdateCallback = t.UpdateCallbackSpec;
t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog; t.UpdateCallbackSpec->ProgressDialog = &t;
t.ItemIndex = index; t.ItemIndex = index;
t.FullPath = fullFilePath; t.FullPath = fullFilePath;
t.FolderOperations = _folderOperations; t.FolderOperations = _folderOperations;

View File

@@ -16,6 +16,7 @@
#include "App.h" #include "App.h"
#include "FormatUtils.h" #include "FormatUtils.h"
#include "LangUtils.h" #include "LangUtils.h"
#include "ListViewDialog.h"
#include "MyLoadMenu.h" #include "MyLoadMenu.h"
#include "PropertyName.h" #include "PropertyName.h"
@@ -50,17 +51,40 @@ void CPanel::InvokeSystemCommand(const char *command)
contextMenu->InvokeCommand(&ci); contextMenu->InvokeCommand(&ci);
} }
static const char * const kSeparator = "----------------------------\n"; static const char * const kSeparator = "------------------------";
static const char * const kSeparatorSmall = "----\n"; static const char * const kSeparatorSmall = "----------------";
static const char * const kPropValueSeparator = ": ";
extern UString ConvertSizeToString(UInt64 value) throw(); extern UString ConvertSizeToString(UInt64 value) throw();
bool IsSizeProp(UINT propID) throw(); bool IsSizeProp(UINT propID) throw();
UString GetOpenArcErrorMessage(UInt32 errorFlags); UString GetOpenArcErrorMessage(UInt32 errorFlags);
static void AddListAscii(CListViewDialog &dialog, const char *s)
{
dialog.Strings.Add((UString)s);
dialog.Values.AddNew();
}
static void AddSeparator(CListViewDialog &dialog)
{
AddListAscii(dialog, kSeparator);
}
static void AddSeparatorSmall(CListViewDialog &dialog)
{
AddListAscii(dialog, kSeparatorSmall);
}
static void AddPropertyPair(const UString &name, const UString &val, CListViewDialog &dialog)
{
dialog.Strings.Add(name);
dialog.Values.Add(val);
}
static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR, static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
const NCOM::CPropVariant &prop, UString &s) const NCOM::CPropVariant &prop, CListViewDialog &dialog)
{ {
if (prop.vt != VT_EMPTY) if (prop.vt != VT_EMPTY)
{ {
@@ -87,23 +111,16 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
if (!val.IsEmpty()) if (!val.IsEmpty())
{ {
s += GetNameOfProperty(propID, nameBSTR); AddPropertyPair(GetNameOfProperty(propID, nameBSTR), val, dialog);
s += kPropValueSeparator;
/*
if (propID == kpidComment)
s.Add_LF();
*/
s += val;
s.Add_LF();
} }
} }
} }
static void AddPropertyString(PROPID propID, UInt64 val, UString &s) static void AddPropertyString(PROPID propID, UInt64 val, CListViewDialog &dialog)
{ {
NCOM::CPropVariant prop = val; NCOM::CPropVariant prop = val;
AddPropertyString(propID, NULL, prop, s); AddPropertyString(propID, NULL, prop, dialog);
} }
@@ -137,7 +154,9 @@ void CPanel::Properties()
} }
{ {
UString message; CListViewDialog message;
// message.DeleteIsAllowed = false;
// message.SelectFirst = false;
CRecordVector<UInt32> operatedIndices; CRecordVector<UInt32> operatedIndices;
GetOperatedItemIndices(operatedIndices); GetOperatedItemIndices(operatedIndices);
@@ -205,15 +224,12 @@ void CPanel::Properties()
} }
} }
} }
message += GetNameOfProperty(propID, name); AddPropertyPair(GetNameOfProperty(propID, name), (UString)s.Ptr(), message);
message += kPropValueSeparator;
message += s.Ptr();
message.Add_LF();
} }
} }
} }
message += kSeparator; AddSeparator(message);
} }
else if (operatedIndices.Size() >= 1) else if (operatedIndices.Size() >= 1)
{ {
@@ -239,8 +255,7 @@ void CPanel::Properties()
{ {
wchar_t temp[32]; wchar_t temp[32];
ConvertUInt32ToString(operatedIndices.Size(), temp); ConvertUInt32ToString(operatedIndices.Size(), temp);
message += MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp); AddPropertyPair(L"", MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp), message);
message.Add_LF();
} }
if (numDirs != 0) if (numDirs != 0)
@@ -250,7 +265,7 @@ void CPanel::Properties()
AddPropertyString(kpidSize, unpackSize, message); AddPropertyString(kpidSize, unpackSize, message);
AddPropertyString(kpidPackSize, packSize, message); AddPropertyString(kpidPackSize, packSize, message);
message += kSeparator; AddSeparator(message);
} }
@@ -309,7 +324,7 @@ void CPanel::Properties()
{ {
const int kNumSpecProps = ARRAY_SIZE(kSpecProps); const int kNumSpecProps = ARRAY_SIZE(kSpecProps);
message += kSeparator; AddSeparator(message);
for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++) for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++)
{ {
@@ -334,7 +349,7 @@ void CPanel::Properties()
UInt32 numProps; UInt32 numProps;
if (getProps->GetArcNumProps2(level, &numProps) == S_OK) if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
{ {
message += kSeparatorSmall; AddSeparatorSmall(message);
for (Int32 i = 0; i < (Int32)numProps; i++) for (Int32 i = 0; i < (Int32)numProps; i++)
{ {
CMyComBSTR name; CMyComBSTR name;
@@ -352,10 +367,15 @@ void CPanel::Properties()
} }
} }
} }
::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES), MB_OK);
message.Title = LangString(IDS_PROPERTIES);
message.NumColumns = 2;
message.Create(GetParent());
} }
} }
void CPanel::EditCut() void CPanel::EditCut()
{ {
// InvokeSystemCommand("cut"); // InvokeSystemCommand("cut");

View File

@@ -79,10 +79,10 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
{ {
UpdateCallbackSpec = new CUpdateCallback100Imp; UpdateCallbackSpec = new CUpdateCallback100Imp;
UpdateCallback = UpdateCallbackSpec; UpdateCallback = UpdateCallbackSpec;
UpdateCallbackSpec->ProgressDialog = &ProgressDialog; UpdateCallbackSpec->ProgressDialog = this;
ProgressDialog.WaitMode = true; WaitMode = true;
ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError; Sync.FinalMessage.ErrorMessage.Title = titleError;
Result = S_OK; Result = S_OK;
UpdateCallbackSpec->Init(); UpdateCallbackSpec->Init();
@@ -95,11 +95,11 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
} }
ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent() MainWindow = panel._mainWindow; // panel.GetParent()
ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
ProgressDialog.MainAddTitle = progressTitle + L' '; MainAddTitle = progressTitle + L' ';
RINOK(Create(progressTitle, ProgressDialog.MainWindow)); RINOK(Create(progressTitle, MainWindow));
return Result; return Result;
} }

View File

@@ -157,7 +157,7 @@ HRESULT CThreadSplit::ProcessVirt()
if (!inFile.GetLength(length)) if (!inFile.GetLength(length))
return GetLastError(); return GetLastError();
CProgressSync &sync = ProgressDialog.Sync; CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(length); sync.Set_NumBytesTotal(length);
UInt64 pos = 0; UInt64 pos = 0;
@@ -306,7 +306,7 @@ void CApp::Split()
CThreadSplit spliter; CThreadSplit spliter;
spliter.NumVolumes = numVolumes; spliter.NumVolumes = numVolumes;
CProgressDialog &progressDialog = spliter.ProgressDialog; CProgressDialog &progressDialog = spliter;
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
UString title = LangString(IDS_SPLITTING); UString title = LangString(IDS_SPLITTING);
@@ -362,7 +362,7 @@ HRESULT CThreadCombine::ProcessVirt()
return res; return res;
} }
CProgressSync &sync = ProgressDialog.Sync; CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(TotalSize); sync.Set_NumBytesTotal(TotalSize);
CMyBuffer bufferObject; CMyBuffer bufferObject;
@@ -534,7 +534,7 @@ void CApp::Combine()
return; return;
} }
CProgressDialog &progressDialog = combiner.ProgressDialog; CProgressDialog &progressDialog = combiner;
progressDialog.ShowCompressionInfo = false; progressDialog.ShowCompressionInfo = false;
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);

View File

@@ -236,7 +236,10 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
AddError_Message_Name(s, name); AddError_Message_Name(s, name);
} }
CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0) CProgressDialog::CProgressDialog():
_timer(0),
CompressingMode(true),
MainWindow(0)
{ {
_isDir = false; _isDir = false;
@@ -975,6 +978,8 @@ bool CProgressDialog::OnExternalCloseMessage()
HideItem(IDB_PROGRESS_BACKGROUND); HideItem(IDB_PROGRESS_BACKGROUND);
HideItem(IDB_PAUSE); HideItem(IDB_PAUSE);
ProcessWasFinished_GuiVirt();
bool thereAreMessages; bool thereAreMessages;
CProgressFinalMessage fm; CProgressFinalMessage fm;
{ {
@@ -982,6 +987,7 @@ bool CProgressDialog::OnExternalCloseMessage()
thereAreMessages = !Sync.Messages.IsEmpty(); thereAreMessages = !Sync.Messages.IsEmpty();
fm = Sync.FinalMessage; fm = Sync.FinalMessage;
} }
if (!fm.ErrorMessage.Message.IsEmpty()) if (!fm.ErrorMessage.Message.IsEmpty())
{ {
MessagesDisplayed = true; MessagesDisplayed = true;
@@ -992,6 +998,7 @@ bool CProgressDialog::OnExternalCloseMessage()
else if (!thereAreMessages) else if (!thereAreMessages)
{ {
MessagesDisplayed = true; MessagesDisplayed = true;
if (!fm.OkMessage.Message.IsEmpty()) if (!fm.OkMessage.Message.IsEmpty())
{ {
if (fm.OkMessage.Title.IsEmpty()) if (fm.OkMessage.Title.IsEmpty())
@@ -1245,11 +1252,24 @@ void CProgressDialog::ProcessWasFinished()
} }
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
CProgressThreadVirt *p = (CProgressThreadVirt *)param;
try
{
p->Process();
p->ThreadFinishedOK = true;
}
catch (...) { p->Result = E_FAIL; }
return 0;
}
HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow) HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow)
{ {
NWindows::CThread thread; NWindows::CThread thread;
RINOK(thread.Create(MyThreadFunction, this)); RINOK(thread.Create(MyThreadFunction, this));
ProgressDialog.Create(title, thread, parentWindow); CProgressDialog::Create(title, thread, parentWindow);
return S_OK; return S_OK;
} }
@@ -1265,7 +1285,7 @@ static void AddMessageToString(UString &dest, const UString &src)
void CProgressThreadVirt::Process() void CProgressThreadVirt::Process()
{ {
CProgressCloser closer(ProgressDialog); CProgressCloser closer(*this);
UString m; UString m;
try { Result = ProcessVirt(); } try { Result = ProcessVirt(); }
catch(const wchar_t *s) { m = s; } catch(const wchar_t *s) { m = s; }
@@ -1293,7 +1313,7 @@ void CProgressThreadVirt::Process()
} }
} }
CProgressSync &sync = ProgressDialog.Sync; CProgressSync &sync = Sync;
NSynchronization::CCriticalSectionLock lock(sync._cs); NSynchronization::CCriticalSectionLock lock(sync._cs);
if (m.IsEmpty()) if (m.IsEmpty())
{ {

View File

@@ -261,7 +261,18 @@ public:
INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
/* how it works:
1) the working thread calls ProcessWasFinished()
that sends kCloseMessage message to CProgressDialog (GUI) thread
2) CProgressDialog (GUI) thread receives kCloseMessage message and
calls ProcessWasFinished_GuiVirt();
So we can implement ProcessWasFinished_GuiVirt() and show special
results window in GUI thread with CProgressDialog as parent window
*/
void ProcessWasFinished(); void ProcessWasFinished();
virtual void ProcessWasFinished_GuiVirt() {}
}; };
@@ -273,7 +284,8 @@ public:
~CProgressCloser() { _p->ProcessWasFinished(); } ~CProgressCloser() { _p->ProcessWasFinished(); }
}; };
class CProgressThreadVirt
class CProgressThreadVirt: public CProgressDialog
{ {
protected: protected:
FStringVector ErrorPaths; FStringVector ErrorPaths;
@@ -281,33 +293,59 @@ protected:
// error if any of HRESULT, ErrorMessage, ErrorPath // error if any of HRESULT, ErrorMessage, ErrorPath
virtual HRESULT ProcessVirt() = 0; virtual HRESULT ProcessVirt() = 0;
void Process();
public: public:
HRESULT Result; HRESULT Result;
bool ThreadFinishedOK; // if there is no fatal exception bool ThreadFinishedOK; // if there is no fatal exception
CProgressDialog ProgressDialog;
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
CProgressThreadVirt *p = (CProgressThreadVirt *)param;
try
{
p->Process();
p->ThreadFinishedOK = true;
}
catch (...) { p->Result = E_FAIL; }
return 0;
}
void Process();
void AddErrorPath(const FString &path) { ErrorPaths.Add(path); } void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
HRESULT Create(const UString &title, HWND parentWindow = 0); HRESULT Create(const UString &title, HWND parentWindow = 0);
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
}; };
UString HResultToMessage(HRESULT errorCode); UString HResultToMessage(HRESULT errorCode);
/*
how it works:
client code inherits CProgressThreadVirt and calls
CProgressThreadVirt::Create()
{
it creates new thread that calls CProgressThreadVirt::Process();
it creates modal progress dialog window with ProgressDialog.Create()
}
CProgressThreadVirt::Process()
{
{
ProcessVirt(); // virtual function that must implement real work
}
if (exceptions) or FinalMessage.ErrorMessage.Message
{
set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message
}
else if (FinalMessage.OkMessage.Message)
{
set message to ProgressDialog.Sync.FinalMessage.OkMessage
}
PostMsg(kCloseMessage);
}
CProgressDialog::OnExternalCloseMessage()
{
if (ProgressDialog.Sync.FinalMessage)
{
WorkWasFinishedVirt();
Show (ProgressDialog.Sync.FinalMessage)
MessagesDisplayed = true;
}
}
*/
#endif #endif

View File

@@ -247,6 +247,7 @@ END
#include "BrowseDialog.rc" #include "BrowseDialog.rc"
#include "ComboDialog.rc" #include "ComboDialog.rc"
#include "CopyDialog.rc" #include "CopyDialog.rc"
#include "EditDialog.rc"
#include "EditPage.rc" #include "EditPage.rc"
#include "FoldersPage.rc" #include "FoldersPage.rc"
#include "LangPage.rc" #include "LangPage.rc"

View File

@@ -5,6 +5,13 @@
<dependency> <dependency>
<dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly>
</dependency> </dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
<asmv3:application> <asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware> <dpiAware>true</dpiAware>

View File

@@ -52,22 +52,9 @@ static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColo
static void AddSizePair(UString &s, UINT resourceID, UInt64 value) static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
{ {
{
wchar_t sz[32];
AddLangString(s, resourceID); AddLangString(s, resourceID);
s += ": "; s += ": ";
ConvertUInt64ToString(value, sz); AddSizeValue(s, value);
s += MyFormatNew(IDS_FILE_SIZE, sz);
}
// s += sz;
if (value >= (1 << 20))
{
char sz[32];
ConvertUInt64ToString(value >> 20, sz);
s += " (";
s += sz;
s += " MB)";
}
s.Add_LF(); s.Add_LF();
} }
@@ -86,16 +73,31 @@ public:
UStringVector *ArchivePathsFull; UStringVector *ArchivePathsFull;
const NWildcard::CCensorNode *WildcardCensor; const NWildcard::CCensorNode *WildcardCensor;
const CExtractOptions *Options; const CExtractOptions *Options;
#ifndef _SFX #ifndef _SFX
CHashBundle *HashBundle; CHashBundle *HashBundle;
virtual void ProcessWasFinished_GuiVirt();
#endif #endif
CMyComPtr<IExtractCallbackUI> ExtractCallback; CMyComPtr<IExtractCallbackUI> ExtractCallback;
UString Title; UString Title;
CPropNameValPairs Pairs;
}; };
#ifndef _SFX
void CThreadExtracting::ProcessWasFinished_GuiVirt()
{
if (HashBundle && !Pairs.IsEmpty())
ShowHashResults(Pairs, *this);
}
#endif
HRESULT CThreadExtracting::ProcessVirt() HRESULT CThreadExtracting::ProcessVirt()
{ {
CDecompressStat Stat; CDecompressStat Stat;
#ifndef _SFX #ifndef _SFX
if (HashBundle) if (HashBundle)
HashBundle->Init(); HashBundle->Init();
@@ -109,16 +111,23 @@ HRESULT CThreadExtracting::ProcessVirt()
HashBundle, HashBundle,
#endif #endif
FinalMessage.ErrorMessage.Message, Stat); FinalMessage.ErrorMessage.Message, Stat);
#ifndef _SFX #ifndef _SFX
if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK()) if (res == S_OK && ExtractCallbackSpec->IsOK())
{
if (HashBundle)
{
AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives);
AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize);
AddHashBundleRes(Pairs, *HashBundle, UString());
}
else if (Options->TestMode)
{ {
UString s; UString s;
AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
if (!HashBundle)
{
if (Stat.NumFolders != 0) if (Stat.NumFolders != 0)
AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders); AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders);
AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles); AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles);
@@ -129,24 +138,19 @@ HRESULT CThreadExtracting::ProcessVirt()
AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams); AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams);
AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize); AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize);
} }
}
if (HashBundle)
{
s.Add_LF();
AddHashBundleRes(s, *HashBundle, UString());
}
s.Add_LF(); s.Add_LF();
AddLangString(s, IDS_MESSAGE_NO_ERRORS); AddLangString(s, IDS_MESSAGE_NO_ERRORS);
FinalMessage.OkMessage.Title = Title; FinalMessage.OkMessage.Title = Title;
FinalMessage.OkMessage.Message = s; FinalMessage.OkMessage.Message = s;
} }
}
#endif #endif
return res; return res;
} }
HRESULT ExtractGUI( HRESULT ExtractGUI(
CCodecs *codecs, CCodecs *codecs,
const CObjectVector<COpenType> &formatIndices, const CObjectVector<COpenType> &formatIndices,
@@ -252,11 +256,11 @@ HRESULT ExtractGUI(
extracter.Title = title; extracter.Title = title;
extracter.ExtractCallbackSpec = extractCallback; extracter.ExtractCallbackSpec = extractCallback;
extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
extracter.ExtractCallback = extractCallback; extracter.ExtractCallback = extractCallback;
extracter.ExtractCallbackSpec->Init(); extracter.ExtractCallbackSpec->Init();
extracter.ProgressDialog.CompressingMode = false; extracter.CompressingMode = false;
extracter.ArchivePaths = &archivePaths; extracter.ArchivePaths = &archivePaths;
extracter.ArchivePathsFull = &archivePathsFull; extracter.ArchivePathsFull = &archivePathsFull;
@@ -266,10 +270,9 @@ HRESULT ExtractGUI(
extracter.HashBundle = hb; extracter.HashBundle = hb;
#endif #endif
extracter.ProgressDialog.IconID = IDI_ICON; extracter.IconID = IDI_ICON;
RINOK(extracter.Create(title, hwndParent)); RINOK(extracter.Create(title, hwndParent));
messageWasDisplayed = extracter.ThreadFinishedOK & messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed;
extracter.ProgressDialog.MessagesDisplayed;
return extracter.Result; return extracter.Result;
} }

View File

@@ -6,8 +6,6 @@
#include <shlwapi.h> #include <shlwapi.h>
#include "../../../../C/Alloc.h"
#include "../../../Common/MyInitGuid.h" #include "../../../Common/MyInitGuid.h"
#include "../../../Common/CommandLineParser.h" #include "../../../Common/CommandLineParser.h"
@@ -16,9 +14,6 @@
#include "../../../Windows/FileDir.h" #include "../../../Windows/FileDir.h"
#include "../../../Windows/NtCheck.h" #include "../../../Windows/NtCheck.h"
#ifdef _WIN32
#include "../../../Windows/MemoryLock.h"
#endif
#include "../Common/ArchiveCommandLine.h" #include "../Common/ArchiveCommandLine.h"
#include "../Common/ExitCode.h" #include "../Common/ExitCode.h"
@@ -37,8 +32,6 @@ using namespace NWindows;
HINSTANCE g_hInstance; HINSTANCE g_hInstance;
bool g_LargePagesMode = false;
#ifndef UNDER_CE #ifndef UNDER_CE
DWORD g_ComCtl32Version; DWORD g_ComCtl32Version;
@@ -126,24 +119,6 @@ static int Main2()
parser.Parse1(commandStrings, options); parser.Parse1(commandStrings, options);
parser.Parse2(options); parser.Parse2(options);
#if defined(_WIN32) && !defined(UNDER_CE)
NSecurity::EnablePrivilege_SymLink();
#endif
#ifdef _7ZIP_LARGE_PAGES
if (options.LargePages)
{
SetLargePageSize();
// note: this process also can inherit that Privilege from parent process
g_LargePagesMode =
#if defined(_WIN32) && !defined(UNDER_CE)
NSecurity::EnablePrivilege_LockMemory();
#else
true;
#endif
}
#endif
CREATE_CODECS_OBJECT CREATE_CODECS_OBJECT
codecs->CaseSensitiveChange = options.CaseSensitiveChange; codecs->CaseSensitiveChange = options.CaseSensitiveChange;
@@ -403,7 +378,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
{ {
return ShowMemErrorMessage(); return ShowMemErrorMessage();
} }
catch(const CArcCmdLineException &e) catch(const CMessagePathException &e)
{ {
ErrorMessage(e); ErrorMessage(e);
return NExitCode::kUserError; return NExitCode::kUserError;

View File

@@ -425,6 +425,14 @@ SOURCE=.\CompressDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\FileManager\EditDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\FileManager\EditDialog.h
# End Source File
# Begin Source File
SOURCE=.\ExtractDialog.cpp SOURCE=.\ExtractDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -433,6 +441,14 @@ SOURCE=.\ExtractDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\FileManager\ListViewDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\FileManager\ListViewDialog.h
# End Source File
# Begin Source File
SOURCE=..\FileManager\OverwriteDialog.cpp SOURCE=..\FileManager\OverwriteDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -975,6 +991,14 @@ SOURCE=..\..\..\Windows\Control\Static.h
# End Group # End Group
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\Clipboard.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Clipboard.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\COM.h SOURCE=..\..\..\Windows\COM.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1051,6 +1075,14 @@ SOURCE=..\..\..\Windows\FileSystem.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\MemoryGlobal.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\MemoryGlobal.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\MemoryLock.cpp SOURCE=..\..\..\Windows\MemoryLock.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

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