This commit is contained in:
Igor Pavlov
2005-06-28 00:00:00 +00:00
committed by Kornel Lesiński
parent 3c510ba80b
commit ac2b563958
83 changed files with 3668 additions and 1316 deletions

View File

@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "7z.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -94,14 +94,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7z Plugin for 7-Zip\0" VALUE "FileDescription", "7z Plugin for 7-Zip\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7z\0" VALUE "InternalName", "7z\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7z.dll\0" VALUE "OriginalFilename", "7z.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -19,14 +19,14 @@ typedef struct _CLzmaInCallbackImp
size_t Size; size_t Size;
} CLzmaInCallbackImp; } CLzmaInCallbackImp;
int LzmaReadImp(void *object, unsigned char **buffer, UInt32 *size) int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
{ {
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object; CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
size_t processedSize; size_t processedSize;
SZ_RESULT res; SZ_RESULT res;
*size = 0; *size = 0;
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize); res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
*size = (UInt32)processedSize; *size = (SizeT)processedSize;
if (processedSize > cb->Size) if (processedSize > cb->Size)
return (int)SZE_FAIL; return (int)SZE_FAIL;
cb->Size -= processedSize; cb->Size -= processedSize;
@@ -37,11 +37,11 @@ int LzmaReadImp(void *object, unsigned char **buffer, UInt32 *size)
#endif #endif
SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder, SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
ISzInStream *inStream, ISzInStream *inStream,
#else #else
Byte *inBuffer, const Byte *inBuffer,
#endif #endif
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
size_t *outSizeProcessed, ISzAlloc *allocMain) size_t *outSizeProcessed, ISzAlloc *allocMain)
@@ -91,13 +91,13 @@ SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder,
{ {
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
CLzmaInCallbackImp lzmaCallback; CLzmaInCallbackImp lzmaCallback;
#else
SizeT inProcessed;
#endif #endif
int lc, lp, pb; CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
size_t lzmaInternalSize;
void *lzmaInternalData;
int result; int result;
UInt32 outSizeProcessedLoc; SizeT outSizeProcessedLoc;
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
lzmaCallback.Size = inSize; lzmaCallback.Size = inSize;
@@ -105,35 +105,36 @@ SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder,
lzmaCallback.InCallback.Read = LzmaReadImp; lzmaCallback.InCallback.Read = LzmaReadImp;
#endif #endif
if (coder->Properties.Capacity < 5) if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
coder->Properties.Capacity) != LZMA_RESULT_OK)
return SZE_FAIL; return SZE_FAIL;
lc = (unsigned char)coder->Properties.Items[0];
if (lc >= (9 * 5 * 5))
return SZE_FAIL;
for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5));
for (lp = 0; lc >= 9; lp++, lc -= 9);
lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb); state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
lzmaInternalData = allocMain->Alloc(lzmaInternalSize); if (state.Probs == 0)
if (lzmaInternalData == 0)
return SZE_OUTOFMEMORY; return SZE_OUTOFMEMORY;
result = LzmaDecode((Byte *)lzmaInternalData, (UInt32)lzmaInternalSize, #ifdef _LZMA_OUT_READ
lc, lp, pb, state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
if (state.Dictionary == 0)
{
allocMain->Free(state.Probs);
return SZE_OUTOFMEMORY;
}
LzmaDecoderInit(&state);
#endif
result = LzmaDecode(&state,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
&lzmaCallback.InCallback, &lzmaCallback.InCallback,
#else #else
inBuffer, (UInt32)inSize, inBuffer, (SizeT)inSize, &inProcessed,
#endif #endif
outBuffer, (UInt32)outSize, outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
&outSizeProcessedLoc);
*outSizeProcessed = (size_t)outSizeProcessedLoc; *outSizeProcessed = (size_t)outSizeProcessedLoc;
allocMain->Free(lzmaInternalData); allocMain->Free(state.Probs);
/* #ifdef _LZMA_OUT_READ
NOT_ENOUGH_MEM error is impossible for this code allocMain->Free(state.Dictionary);
if (result = LZMA_RESULT_NOT_ENOUGH_MEM) #endif
return SZE_OUTOFMEMORY;
*/
if (result == LZMA_RESULT_DATA_ERROR) if (result == LZMA_RESULT_DATA_ERROR)
return SZE_DATA_ERROR; return SZE_DATA_ERROR;
if (result != LZMA_RESULT_OK) if (result != LZMA_RESULT_OK)

View File

@@ -9,11 +9,11 @@
#include "7zIn.h" #include "7zIn.h"
#endif #endif
SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder, SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
ISzInStream *stream, ISzInStream *stream,
#else #else
Byte *inBuffer, const Byte *inBuffer,
#endif #endif
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
size_t *outSizeProcessed, ISzAlloc *allocMain); size_t *outSizeProcessed, ISzAlloc *allocMain);

View File

@@ -811,7 +811,9 @@ SZ_RESULT SzReadStreamsInfo(
{ {
UInt64 type; UInt64 type;
RINOK(SzReadID(sd, &type)); RINOK(SzReadID(sd, &type));
switch(type) if ((UInt64)(int)type != type)
return SZE_FAIL;
switch((int)type)
{ {
case k7zIdEnd: case k7zIdEnd:
return SZ_OK; return SZ_OK;
@@ -989,8 +991,13 @@ SZ_RESULT SzReadHeader2(
if (type == k7zIdEnd) if (type == k7zIdEnd)
break; break;
RINOK(SzReadNumber(sd, &size)); RINOK(SzReadNumber(sd, &size));
switch(type) if ((UInt64)(int)type != type)
{
RINOK(SzSkeepDataSize(sd, size));
}
else
switch((int)type)
{ {
case k7zIdName: case k7zIdName:
{ {

View File

@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "arj.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,13,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,13,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -94,14 +94,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "Arj Plugin for 7-Zip\0" VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
VALUE "FileVersion", "4, 13, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "arj\0" VALUE "InternalName", "arj\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "arj.dll\0" VALUE "OriginalFilename", "arj.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 13, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -21,8 +21,8 @@ CDecoder::CDecoder()
void CDecoder::ReleaseStreams() void CDecoder::ReleaseStreams()
{ {
// m_OutWindowStream.ReleaseStream(); m_OutWindowStream.ReleaseStream();
// m_InBitStream.ReleaseStream(); m_InBitStream.ReleaseStream();
m_i86TranslationOutStreamSpec->ReleaseStream(); m_i86TranslationOutStreamSpec->ReleaseStream();
} }

View File

@@ -17,13 +17,11 @@ HRESULT CDecoder::Flush()
return m_OutWindowStream.Flush(); return m_OutWindowStream.Flush();
} }
/*
void CDecoder::ReleaseStreams() void CDecoder::ReleaseStreams()
{ {
m_OutWindowStream.ReleaseStream(); m_OutWindowStream.ReleaseStream();
m_InBitStream.ReleaseStream(); m_InBitStream.ReleaseStream();
} }
*/
void CDecoder::DeCodeLevelTable(Byte *newLevels, int numLevels) void CDecoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
{ {
@@ -169,7 +167,7 @@ public:
~CCoderReleaser() ~CCoderReleaser()
{ {
m_Coder->Flush(); m_Coder->Flush();
// m_Coder->ReleaseStreams(); m_Coder->ReleaseStreams();
} }
}; };

View File

@@ -66,7 +66,7 @@ public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
HRESULT Flush(); HRESULT Flush();
// void ReleaseStreams(); void ReleaseStreams();
STDMETHOD(Code)(ISequentialInStream *inStream, STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,19,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,19,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov \0" VALUE "CompanyName", "Igor Pavlov \0"
VALUE "FileDescription", "Cab Plugin for 7-Zip\0" VALUE "FileDescription", "Cab Plugin for 7-Zip\0"
VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "cab\0" VALUE "InternalName", "cab\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "cab.dll\0" VALUE "OriginalFilename", "cab.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "zip.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,19,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,19,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -94,14 +94,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "Zip Plugin for 7-Zip\0" VALUE "FileDescription", "Zip Plugin for 7-Zip\0"
VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "zip\0" VALUE "InternalName", "zip\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "zip.dll\0" VALUE "OriginalFilename", "zip.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip Standalone Console version\0" VALUE "FileDescription", "7-Zip Standalone Console version\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7za\0" VALUE "InternalName", "7za\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7za.exe\0" VALUE "OriginalFilename", "7za.exe\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -34,7 +34,7 @@ using namespace NCommandLineParser;
extern CStdOutStream *g_StdStream; extern CStdOutStream *g_StdStream;
static const char *kCopyrightString = static const char *kCopyrightString =
"\n7-Zip SFX 4.20 Copyright (c) 1999-2005 Igor Pavlov 2005-05-30\n"; "\n7-Zip SFX 4.23 Copyright (c) 1999-2005 Igor Pavlov 2005-06-29\n";
static const int kNumSwitches = 6; static const int kNumSwitches = 6;

View File

@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "7z.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -94,14 +94,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7z SFX (Console version)\0" VALUE "FileDescription", "7z SFX (Console version)\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7zCon.sfx\0" VALUE "InternalName", "7zCon.sfx\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7zCon.sfx\0" VALUE "OriginalFilename", "7zCon.sfx\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -76,8 +76,8 @@ IDI_ICON3 ICON DISCARDABLE "setup.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -95,14 +95,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7z Self-Extract Setup\0" VALUE "FileDescription", "7z Self-Extract Setup\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7zS.sfx\0" VALUE "InternalName", "7zS.sfx\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7zS.sfx\0" VALUE "OriginalFilename", "7zS.sfx\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -80,8 +80,8 @@ IDI_ICON3 ICON DISCARDABLE "7z.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -99,14 +99,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7z SFX\0" VALUE "FileDescription", "7z SFX\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7zWin.sfx\0" VALUE "InternalName", "7zWin.sfx\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7zWin.sfx\0" VALUE "OriginalFilename", "7zWin.sfx\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -79,7 +79,12 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
if(processedSize != NULL) if(processedSize != NULL)
*processedSize = 0; *processedSize = 0;
ssize_t res = read(0, data, (size_t)size); ssize_t res;
do
{
res = read(0, data, (size_t)size);
}
while (res < 0 && (errno == EINTR));
if (res == -1) if (res == -1)
return E_FAIL; return E_FAIL;
if(processedSize != NULL) if(processedSize != NULL)
@@ -243,7 +248,12 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
#else #else
ssize_t res = write(1, data, (size_t)size); ssize_t res;
do
{
res = write(1, data, (size_t)size);
}
while (res < 0 && (errno == EINTR));
if (res == -1) if (res == -1)
return E_FAIL; return E_FAIL;
if(processedSize != NULL) if(processedSize != NULL)

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,19,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,19,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", " \0" VALUE "CompanyName", " \0"
VALUE "FileDescription", "Deflate Coder\0" VALUE "FileDescription", "Deflate Coder\0"
VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "Deflate\0" VALUE "InternalName", "Deflate\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "Deflate.dll\0" VALUE "OriginalFilename", "Deflate.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -29,7 +29,7 @@ public:
void Free(); void Free();
CLZOutWindow(): _buffer(0), _stream(0) {} CLZOutWindow(): _buffer(0), _stream(0) {}
~CLZOutWindow() { Free(); /* ReleaseStream(); */ } ~CLZOutWindow() { Free(); ReleaseStream(); }
bool Create(UInt32 windowSize); bool Create(UInt32 windowSize);
void SetStream(ISequentialOutStream *stream); void SetStream(ISequentialOutStream *stream);

View File

@@ -384,7 +384,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
if (prop.vt != VT_UI4) if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
UInt32 numFastBytes = prop.ulVal; UInt32 numFastBytes = prop.ulVal;
if(numFastBytes < 2 || numFastBytes > kMatchMaxLen) if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
return E_INVALIDARG; return E_INVALIDARG;
_numFastBytes = numFastBytes; _numFastBytes = numFastBytes;
break; break;
@@ -652,18 +652,14 @@ HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
{ {
backRes = repMaxIndex; backRes = repMaxIndex;
lenRes = repLens[repMaxIndex]; lenRes = repLens[repMaxIndex];
MovePos(lenRes - 1); return MovePos(lenRes - 1);
return S_OK;
} }
if(lenMain > _numFastBytes) if(lenMain > _numFastBytes)
{ {
UInt32 backMain = (lenMain < _numFastBytes) ? _matchDistances[lenMain] : backRes = _matchDistances[_numFastBytes] + kNumRepDistances;
_matchDistances[_numFastBytes];
backRes = backMain + kNumRepDistances;
MovePos(lenMain - 1);
lenRes = lenMain; lenRes = lenMain;
return S_OK; return MovePos(lenMain - 1);
} }
Byte currentByte = _matchFinder->GetIndexByte(0 - 1); Byte currentByte = _matchFinder->GetIndexByte(0 - 1);
@@ -1099,15 +1095,13 @@ HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRe
{ {
backRes = repMaxIndex; backRes = repMaxIndex;
lenRes = repLens[repMaxIndex]; lenRes = repLens[repMaxIndex];
MovePos(lenRes - 1); return MovePos(lenRes - 1);
return S_OK;
} }
if(lenMain >= _numFastBytes) if(lenMain >= _numFastBytes)
{ {
backRes = _matchDistances[_numFastBytes] + kNumRepDistances; backRes = _matchDistances[_numFastBytes] + kNumRepDistances;
MovePos(lenMain - 1);
lenRes = lenMain; lenRes = lenMain;
return S_OK; return MovePos(lenMain - 1);
} }
while (lenMain > 2) while (lenMain > 2)
{ {
@@ -1126,8 +1120,7 @@ HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRe
{ {
backRes = repMaxIndex; backRes = repMaxIndex;
lenRes = repLens[repMaxIndex]; lenRes = repLens[repMaxIndex];
MovePos(lenRes - 1); return MovePos(lenRes - 1);
return S_OK;
} }
} }
@@ -1163,9 +1156,8 @@ HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRe
} }
} }
backRes = backMain + kNumRepDistances; backRes = backMain + kNumRepDistances;
MovePos(lenMain - 2);
lenRes = lenMain; lenRes = lenMain;
return S_OK; return MovePos(lenMain - 2);
} }
backRes = UInt32(-1); backRes = UInt32(-1);
lenRes = 1; lenRes = 1;

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,17,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,17,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "LZMA Codec\0" VALUE "FileDescription", "LZMA Codec\0"
VALUE "FileVersion", "4, 17, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "LZMA\0" VALUE "InternalName", "LZMA\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "LZMA.dll\0" VALUE "OriginalFilename", "LZMA.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 17, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -19,8 +19,6 @@
#include "../../../Common/StringConvert.h" #include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h" #include "../../../Common/StringToInt.h"
// #include "Windows/PropVariant.h"
#include "../../Common/FileStreams.h" #include "../../Common/FileStreams.h"
#include "../LZMA/LZMADecoder.h" #include "../LZMA/LZMADecoder.h"
@@ -131,7 +129,7 @@ static bool GetNumber(const wchar_t *s, UInt32 &value)
int main2(int n, const char *args[]) int main2(int n, const char *args[])
{ {
fprintf(stderr, "\nLZMA 4.17 Copyright (c) 1999-2004 Igor Pavlov 2005-04-18\n"); fprintf(stderr, "\nLZMA 4.23 Copyright (c) 1999-2005 Igor Pavlov 2005-06-29\n");
if (n == 1) if (n == 1)
{ {

View File

@@ -13,8 +13,8 @@
#define LZMA_SIZE_OFFSET 6 #define LZMA_SIZE_OFFSET 6
int LzmaRamGetUncompressedSize( int LzmaRamGetUncompressedSize(
unsigned char *inBuffer, const unsigned char *inBuffer,
size_t inSize, size_t inSize,
size_t *outSize) size_t *outSize)
{ {
unsigned int i; unsigned int i;
@@ -33,7 +33,7 @@ int LzmaRamGetUncompressedSize(
#define SZE_OUTOFMEMORY (2) #define SZE_OUTOFMEMORY (2)
int LzmaRamDecompress( int LzmaRamDecompress(
unsigned char *inBuffer, const unsigned char *inBuffer,
size_t inSize, size_t inSize,
unsigned char *outBuffer, unsigned char *outBuffer,
size_t outSize, size_t outSize,
@@ -41,37 +41,30 @@ int LzmaRamDecompress(
void * (*allocFunc)(size_t size), void * (*allocFunc)(size_t size),
void (*freeFunc)(void *)) void (*freeFunc)(void *))
{ {
int lc, lp, pb; CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */
size_t lzmaInternalSize;
void *lzmaInternalData;
int result; int result;
UInt32 outSizeProcessedLoc; SizeT outSizeProcessedLoc;
SizeT inProcessed;
int useFilter;
int useFilter = inBuffer[0]; if (inSize < LZMA_PROPS_SIZE)
return 1;
useFilter = inBuffer[0];
*outSizeProcessed = 0; *outSizeProcessed = 0;
if (useFilter > 1) if (useFilter > 1)
return 1; return 1;
if (inSize < LZMA_PROPS_SIZE) if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return 1; return 1;
lc = inBuffer[1]; state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (lc >= (9 * 5 * 5)) if (state.Probs == 0)
return 1;
for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5));
for (lp = 0; lc >= 9; lp++, lc -= 9);
lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb);
lzmaInternalData = allocFunc(lzmaInternalSize);
if (lzmaInternalData == 0)
return SZE_OUTOFMEMORY; return SZE_OUTOFMEMORY;
result = LzmaDecode((unsigned char *)lzmaInternalData, (UInt32)lzmaInternalSize, result = LzmaDecode(&state,
lc, lp, pb, inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed,
inBuffer + LZMA_PROPS_SIZE, (UInt32)inSize - LZMA_PROPS_SIZE, outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
outBuffer, (UInt32)outSize, freeFunc(state.Probs);
&outSizeProcessedLoc);
freeFunc(lzmaInternalData);
if (result != LZMA_RESULT_OK) if (result != LZMA_RESULT_OK)
return 1; return 1;
*outSizeProcessed = (size_t)outSizeProcessedLoc; *outSizeProcessed = (size_t)outSizeProcessedLoc;
@@ -84,5 +77,3 @@ int LzmaRamDecompress(
} }
return 0; return 0;
} }

View File

@@ -18,7 +18,7 @@ LzmaRamGetUncompressedSize:
*/ */
int LzmaRamGetUncompressedSize( int LzmaRamGetUncompressedSize(
unsigned char *inBuffer, const unsigned char *inBuffer,
size_t inSize, size_t inSize,
size_t *outSize); size_t *outSize);
@@ -44,7 +44,7 @@ With default lzma settings it's about 16 KB.
*/ */
int LzmaRamDecompress( int LzmaRamDecompress(
unsigned char *inBuffer, const unsigned char *inBuffer,
size_t inSize, size_t inSize,
unsigned char *outBuffer, unsigned char *outBuffer,
size_t outSize, size_t outSize,

View File

@@ -2,7 +2,7 @@
LzmaDecode.c LzmaDecode.c
LZMA Decoder (optimized for Speed version) LZMA Decoder (optimized for Speed version)
LZMA SDK 4.17 Copyright (c) 1999-2005 Igor Pavlov (2005-04-05) LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10)
http://www.7-zip.org/ http://www.7-zip.org/
LZMA SDK is licensed under two licenses: LZMA SDK is licensed under two licenses:
@@ -40,7 +40,7 @@
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
#define RC_TEST { if (Buffer == BufferLim) \ #define RC_TEST { if (Buffer == BufferLim) \
{ UInt32 size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 #define RC_INIT Buffer = BufferLim = 0; RC_INIT2
@@ -121,109 +121,86 @@
StopCompilingDueBUG StopCompilingDueBUG
#endif #endif
#ifdef _LZMA_OUT_READ int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
typedef struct _LzmaVarState
{ {
Byte *Buffer; unsigned char prop0;
Byte *BufferLim; if (size < LZMA_PROPERTIES_SIZE)
UInt32 Range; return LZMA_RESULT_DATA_ERROR;
UInt32 Code; prop0 = propsData[0];
#ifdef _LZMA_IN_CB if (prop0 >= (9 * 5 * 5))
ILzmaInCallback *InCallback; return LZMA_RESULT_DATA_ERROR;
#endif {
Byte *Dictionary; for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
UInt32 DictionarySize; for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
UInt32 DictionaryPos; propsRes->lc = prop0;
UInt32 GlobalPos; /*
UInt32 Reps[4]; unsigned char remainder = (unsigned char)(prop0 / 9);
int lc; propsRes->lc = prop0 % 9;
int lp; propsRes->pb = remainder / 5;
int pb; propsRes->lp = remainder % 5;
int State; */
int RemainLen; }
Byte TempDictionary[4];
} LzmaVarState;
int LzmaDecoderInit( #ifdef _LZMA_OUT_READ
unsigned char *buffer, UInt32 bufferSize, {
int lc, int lp, int pb, int i;
unsigned char *dictionary, UInt32 dictionarySize, propsRes->DictionarySize = 0;
#ifdef _LZMA_IN_CB for (i = 0; i < 4; i++)
ILzmaInCallback *InCallback propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
#else if (propsRes->DictionarySize == 0)
unsigned char *inStream, UInt32 inSize propsRes->DictionarySize = 1;
#endif }
)
{
Byte *Buffer;
Byte *BufferLim;
UInt32 Range;
UInt32 Code;
LzmaVarState *vs = (LzmaVarState *)buffer;
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
UInt32 i;
if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
return LZMA_RESULT_NOT_ENOUGH_MEM;
vs->Dictionary = dictionary;
vs->DictionarySize = dictionarySize;
vs->DictionaryPos = 0;
vs->GlobalPos = 0;
vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
vs->lc = lc;
vs->lp = lp;
vs->pb = pb;
vs->State = 0;
vs->RemainLen = 0;
dictionary[dictionarySize - 1] = 0;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif #endif
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
vs->Range = Range;
vs->Code = Code;
#ifdef _LZMA_IN_CB
vs->InCallback = InCallback;
#endif
return LZMA_RESULT_OK; return LZMA_RESULT_OK;
} }
int LzmaDecode(unsigned char *buffer, #define kLzmaStreamWasFinishedId (-1)
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed) int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{ {
LzmaVarState *vs = (LzmaVarState *)buffer; CProb *p = vs->Probs;
Byte *Buffer = vs->Buffer; SizeT nowPos = 0;
Byte *BufferLim = vs->BufferLim; Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
#ifdef _LZMA_OUT_READ
UInt32 Range = vs->Range; UInt32 Range = vs->Range;
UInt32 Code = vs->Code; UInt32 Code = vs->Code;
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback = vs->InCallback; const Byte *Buffer = vs->Buffer;
const Byte *BufferLim = vs->BufferLim;
#else
const Byte *Buffer = inStream;
const Byte *BufferLim = inStream + inSize;
#endif #endif
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
int state = vs->State; int state = vs->State;
Byte previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << (vs->pb)) - 1;
UInt32 literalPosMask = (1 << (vs->lp)) - 1;
int lc = vs->lc;
int len = vs->RemainLen; int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos; UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
Byte *dictionary = vs->Dictionary; Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->DictionarySize; UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos; UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4]; Byte tempDictionary[4];
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0) if (dictionarySize == 0)
{ {
dictionary = tempDictionary; dictionary = tempDictionary;
@@ -231,12 +208,27 @@ int LzmaDecode(unsigned char *buffer,
tempDictionary[0] = vs->TempDictionary[0]; tempDictionary[0] = vs->TempDictionary[0];
} }
if (len == -1) if (len == kLzmaNeedInitId)
{ {
*outSizeProcessed = 0; {
return LZMA_RESULT_OK; UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
}
len = 0;
} }
while(len != 0 && nowPos < outSize) while(len != 0 && nowPos < outSize)
{ {
UInt32 pos = dictionaryPos - rep0; UInt32 pos = dictionaryPos - rep0;
@@ -251,50 +243,37 @@ int LzmaDecode(unsigned char *buffer,
previousByte = dictionary[dictionarySize - 1]; previousByte = dictionary[dictionarySize - 1];
else else
previousByte = dictionary[dictionaryPos - 1]; previousByte = dictionary[dictionaryPos - 1];
#else
int LzmaDecode( #else /* if !_LZMA_OUT_READ */
Byte *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
unsigned char *inStream, UInt32 inSize,
#endif
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
CProb *p = (CProb *)buffer;
UInt32 i;
int state = 0; int state = 0;
Byte previousByte = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << pb) - 1;
UInt32 literalPosMask = (1 << lp) - 1;
int len = 0; int len = 0;
const Byte *Buffer;
Byte *Buffer; const Byte *BufferLim;
Byte *BufferLim;
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
if (bufferSize < numProbs * sizeof(CProb))
return LZMA_RESULT_NOT_ENOUGH_MEM;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
RC_INIT; RC_INIT;
#else #else
RC_INIT(inStream, inSize); RC_INIT(inStream, inSize);
#endif #endif
#endif
*outSizeProcessed = 0; #endif /* _LZMA_OUT_READ */
while(nowPos < outSize) while(nowPos < outSize)
{ {
CProb *prob; CProb *prob;
@@ -352,6 +331,9 @@ int LzmaDecode(
outStream[nowPos++] = previousByte; outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte; dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize) if (++dictionaryPos == dictionarySize)
dictionaryPos = 0; dictionaryPos = 0;
@@ -387,12 +369,14 @@ int LzmaDecode(
UInt32 pos; UInt32 pos;
#endif #endif
UpdateBit0(prob); UpdateBit0(prob);
if (nowPos
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
+ globalPos if (distanceLimit == 0)
#endif #else
== 0) if (nowPos == 0)
#endif
return LZMA_RESULT_DATA_ERROR; return LZMA_RESULT_DATA_ERROR;
state = state < kNumLitStates ? 9 : 11; state = state < kNumLitStates ? 9 : 11;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0; pos = dictionaryPos - rep0;
@@ -406,6 +390,11 @@ int LzmaDecode(
previousByte = outStream[nowPos - rep0]; previousByte = outStream[nowPos - rep0];
#endif #endif
outStream[nowPos++] = previousByte; outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
#endif
continue; continue;
} }
else else
@@ -532,18 +521,26 @@ int LzmaDecode(
if (++rep0 == (UInt32)(0)) if (++rep0 == (UInt32)(0))
{ {
/* it's for stream version */ /* it's for stream version */
len = -1; len = kLzmaStreamWasFinishedId;
break; break;
} }
} }
len += kMatchMinLen; len += kMatchMinLen;
if (rep0 > nowPos #ifdef _LZMA_OUT_READ
#ifdef _LZMA_OUT_READ if (rep0 > distanceLimit)
+ globalPos || rep0 > dictionarySize #else
#endif if (rep0 > nowPos)
) #endif
return LZMA_RESULT_DATA_ERROR; return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do do
{ {
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
@@ -566,12 +563,11 @@ int LzmaDecode(
RC_NORMALIZE; RC_NORMALIZE;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
vs->Range = Range; vs->Range = Range;
vs->Code = Code; vs->Code = Code;
vs->DictionaryPos = dictionaryPos; vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + nowPos; vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0; vs->Reps[0] = rep0;
vs->Reps[1] = rep1; vs->Reps[1] = rep1;
vs->Reps[2] = rep2; vs->Reps[2] = rep2;
@@ -581,6 +577,12 @@ int LzmaDecode(
vs->TempDictionary[0] = tempDictionary[0]; vs->TempDictionary[0] = tempDictionary[0];
#endif #endif
#ifdef _LZMA_IN_CB
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
#else
*inSizeProcessed = (SizeT)(Buffer - inStream);
#endif
*outSizeProcessed = nowPos; *outSizeProcessed = nowPos;
return LZMA_RESULT_OK; return LZMA_RESULT_OK;
} }

View File

@@ -2,7 +2,7 @@
LzmaDecode.h LzmaDecode.h
LZMA Decoder interface LZMA Decoder interface
LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18) LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
http://www.7-zip.org/ http://www.7-zip.org/
LZMA SDK is licensed under two licenses: LZMA SDK is licensed under two licenses:
@@ -35,6 +35,9 @@
/* #define _LZMA_LOC_OPT */ /* #define _LZMA_LOC_OPT */
/* Enable local speed optimizations inside code */ /* Enable local speed optimizations inside code */
/* #define _LZMA_SYSTEM_SIZE_T */
/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/
#ifndef UInt32 #ifndef UInt32
#ifdef _LZMA_UINT32_IS_ULONG #ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long #define UInt32 unsigned long
@@ -43,6 +46,15 @@
#endif #endif
#endif #endif
#ifndef SizeT
#ifdef _LZMA_SYSTEM_SIZE_T
#include <stddef.h>
#define SizeT size_t
#else
#define SizeT UInt32
#endif
#endif
#ifdef _LZMA_PROB32 #ifdef _LZMA_PROB32
#define CProb UInt32 #define CProb UInt32
#else #else
@@ -51,50 +63,69 @@
#define LZMA_RESULT_OK 0 #define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1 #define LZMA_RESULT_DATA_ERROR 1
#define LZMA_RESULT_NOT_ENOUGH_MEM 2
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
typedef struct _ILzmaInCallback typedef struct _ILzmaInCallback
{ {
int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
} ILzmaInCallback; } ILzmaInCallback;
#endif #endif
#define LZMA_BASE_SIZE 1846 #define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768 #define LZMA_LIT_SIZE 768
/* #define LZMA_PROPERTIES_SIZE 5
bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb)
bufferSize += 100 in case of _LZMA_OUT_READ typedef struct _CLzmaProperties
by default CProb is unsigned short, {
but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) int lc;
*/ int lp;
int pb;
#ifdef _LZMA_OUT_READ
UInt32 DictionarySize;
#endif
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
#ifdef _LZMA_IN_CB
const unsigned char *Buffer;
const unsigned char *BufferLim;
#endif
#ifdef _LZMA_OUT_READ
unsigned char *Dictionary;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen;
unsigned char TempDictionary[4];
#endif
} CLzmaDecoderState;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
int LzmaDecoderInit( #define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
unsigned char *dictionary, UInt32 dictionarySize,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback
#else
unsigned char *inStream, UInt32 inSize
#endif
);
#endif #endif
int LzmaDecode( int LzmaDecode(CLzmaDecoderState *vs,
unsigned char *buffer, #ifdef _LZMA_IN_CB
#ifndef _LZMA_OUT_READ
UInt32 bufferSize,
int lc, int lp, int pb,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback, ILzmaInCallback *inCallback,
#else #else
unsigned char *inStream, UInt32 inSize, const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif #endif
#endif unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed);
#endif #endif

View File

@@ -2,7 +2,7 @@
LzmaDecodeSize.c LzmaDecodeSize.c
LZMA Decoder (optimized for Size version) LZMA Decoder (optimized for Size version)
LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18) LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10)
http://www.7-zip.org/ http://www.7-zip.org/
LZMA SDK is licensed under two licenses: LZMA SDK is licensed under two licenses:
@@ -34,8 +34,8 @@
typedef struct _CRangeDecoder typedef struct _CRangeDecoder
{ {
Byte *Buffer; const Byte *Buffer;
Byte *BufferLim; const Byte *BufferLim;
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
@@ -50,7 +50,7 @@ Byte RangeDecoderReadByte(CRangeDecoder *rd)
if (rd->Buffer == rd->BufferLim) if (rd->Buffer == rd->BufferLim)
{ {
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
UInt32 size; SizeT size;
rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
rd->BufferLim = rd->Buffer + size; rd->BufferLim = rd->Buffer + size;
if (size == 0) if (size == 0)
@@ -70,7 +70,7 @@ void RangeDecoderInit(CRangeDecoder *rd,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback ILzmaInCallback *inCallback
#else #else
Byte *stream, UInt32 bufferSize const Byte *stream, SizeT bufferSize
#endif #endif
) )
{ {
@@ -330,86 +330,88 @@ int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
StopCompilingDueBUG StopCompilingDueBUG
#endif #endif
#ifdef _LZMA_OUT_READ int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
typedef struct _LzmaVarState
{ {
CRangeDecoder RangeDecoder; unsigned char prop0;
Byte *Dictionary; if (size < LZMA_PROPERTIES_SIZE)
UInt32 DictionarySize; return LZMA_RESULT_DATA_ERROR;
UInt32 DictionaryPos; prop0 = propsData[0];
UInt32 GlobalPos; if (prop0 >= (9 * 5 * 5))
UInt32 Reps[4]; return LZMA_RESULT_DATA_ERROR;
int lc; {
int lp; for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
int pb; for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
int State; propsRes->lc = prop0;
int RemainLen; /*
Byte TempDictionary[4]; unsigned char remainder = (unsigned char)(prop0 / 9);
} LzmaVarState; propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
int LzmaDecoderInit( #ifdef _LZMA_OUT_READ
unsigned char *buffer, UInt32 bufferSize, {
int lc, int lp, int pb, int i;
unsigned char *dictionary, UInt32 dictionarySize, propsRes->DictionarySize = 0;
#ifdef _LZMA_IN_CB for (i = 0; i < 4; i++)
ILzmaInCallback *inCallback propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
#else if (propsRes->DictionarySize == 0)
unsigned char *inStream, UInt32 inSize propsRes->DictionarySize = 1;
#endif }
) #endif
{
LzmaVarState *vs = (LzmaVarState *)buffer;
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
UInt32 i;
if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
return LZMA_RESULT_NOT_ENOUGH_MEM;
vs->Dictionary = dictionary;
vs->DictionarySize = dictionarySize;
vs->DictionaryPos = 0;
vs->GlobalPos = 0;
vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
vs->lc = lc;
vs->lp = lp;
vs->pb = pb;
vs->State = 0;
vs->RemainLen = 0;
dictionary[dictionarySize - 1] = 0;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
RangeDecoderInit(&vs->RangeDecoder,
#ifdef _LZMA_IN_CB
inCallback
#else
inStream, inSize
#endif
);
return LZMA_RESULT_OK; return LZMA_RESULT_OK;
} }
int LzmaDecode(unsigned char *buffer, #define kLzmaStreamWasFinishedId (-1)
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed) int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{ {
LzmaVarState *vs = (LzmaVarState *)buffer; CProb *p = vs->Probs;
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); SizeT nowPos = 0;
CRangeDecoder rd = vs->RangeDecoder; Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
CRangeDecoder rd;
#ifdef _LZMA_OUT_READ
int state = vs->State; int state = vs->State;
Byte previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << (vs->pb)) - 1;
UInt32 literalPosMask = (1 << (vs->lp)) - 1;
int lc = vs->lc;
int len = vs->RemainLen; int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos; UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
Byte *dictionary = vs->Dictionary; Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->DictionarySize; UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos; UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4]; Byte tempDictionary[4];
rd.Range = vs->Range;
rd.Code = vs->Code;
#ifdef _LZMA_IN_CB
rd.Buffer = vs->Buffer;
rd.BufferLim = vs->BufferLim;
#else
rd.Buffer = inStream;
rd.BufferLim = inStream + inSize;
#endif
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0) if (dictionarySize == 0)
{ {
dictionary = tempDictionary; dictionary = tempDictionary;
@@ -417,12 +419,35 @@ int LzmaDecode(unsigned char *buffer,
tempDictionary[0] = vs->TempDictionary[0]; tempDictionary[0] = vs->TempDictionary[0];
} }
if (len == -1) if (len == kLzmaNeedInitId)
{ {
*outSizeProcessed = 0; {
return LZMA_RESULT_OK; UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
RangeDecoderInit(&rd,
#ifdef _LZMA_IN_CB
InCallback
#else
inStream, inSize
#endif
);
#ifdef _LZMA_IN_CB
if (rd.Result != LZMA_RESULT_OK)
return rd.Result;
#endif
if (rd.ExtraBytes != 0)
return LZMA_RESULT_DATA_ERROR;
}
len = 0;
} }
while(len != 0 && nowPos < outSize) while(len != 0 && nowPos < outSize)
{ {
UInt32 pos = dictionaryPos - rep0; UInt32 pos = dictionaryPos - rep0;
@@ -437,44 +462,48 @@ int LzmaDecode(unsigned char *buffer,
previousByte = dictionary[dictionarySize - 1]; previousByte = dictionary[dictionarySize - 1];
else else
previousByte = dictionary[dictionaryPos - 1]; previousByte = dictionary[dictionaryPos - 1];
#else
int LzmaDecode( #ifdef _LZMA_IN_CB
Byte *buffer, UInt32 bufferSize, rd.Result = LZMA_RESULT_OK;
int lc, int lp, int pb, #endif
#ifdef _LZMA_IN_CB rd.ExtraBytes = 0;
ILzmaInCallback *inCallback,
#else #else /* if !_LZMA_OUT_READ */
unsigned char *inStream, UInt32 inSize,
#endif
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
CProb *p = (CProb *)buffer;
CRangeDecoder rd;
UInt32 i;
int state = 0; int state = 0;
Byte previousByte = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << pb) - 1;
UInt32 literalPosMask = (1 << lp) - 1;
int len = 0; int len = 0;
if (bufferSize < numProbs * sizeof(CProb))
return LZMA_RESULT_NOT_ENOUGH_MEM; #ifndef _LZMA_IN_CB
for (i = 0; i < numProbs; i++) *inSizeProcessed = 0;
p[i] = kBitModelTotal >> 1; #endif
RangeDecoderInit(&rd, *outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
RangeDecoderInit(&rd,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
inCallback InCallback
#else #else
inStream, inSize inStream, inSize
#endif #endif
); );
#endif
*outSizeProcessed = 0; #ifdef _LZMA_IN_CB
if (rd.Result != LZMA_RESULT_OK)
return rd.Result;
#endif
if (rd.ExtraBytes != 0)
return LZMA_RESULT_DATA_ERROR;
#endif /* _LZMA_OUT_READ */
while(nowPos < outSize) while(nowPos < outSize)
{ {
int posState = (int)( int posState = (int)(
@@ -518,6 +547,9 @@ int LzmaDecode(
previousByte = LzmaLiteralDecode(probs, &rd); previousByte = LzmaLiteralDecode(probs, &rd);
outStream[nowPos++] = previousByte; outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte; dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize) if (++dictionaryPos == dictionarySize)
dictionaryPos = 0; dictionaryPos = 0;
@@ -537,14 +569,14 @@ int LzmaDecode(
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
UInt32 pos; UInt32 pos;
#endif #endif
if (
(nowPos #ifdef _LZMA_OUT_READ
#ifdef _LZMA_OUT_READ if (distanceLimit == 0)
+ globalPos #else
#endif if (nowPos == 0)
) #endif
== 0)
return LZMA_RESULT_DATA_ERROR; return LZMA_RESULT_DATA_ERROR;
state = state < 7 ? 9 : 11; state = state < 7 ? 9 : 11;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0; pos = dictionaryPos - rep0;
@@ -558,6 +590,11 @@ int LzmaDecode(
previousByte = outStream[nowPos - rep0]; previousByte = outStream[nowPos - rep0];
#endif #endif
outStream[nowPos++] = previousByte; outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
#endif
continue; continue;
} }
} }
@@ -612,23 +649,29 @@ int LzmaDecode(
} }
else else
rep0 = posSlot; rep0 = posSlot;
rep0++; if (++rep0 == (UInt32)(0))
} {
if (rep0 == (UInt32)(0)) /* it's for stream version */
{ len = kLzmaStreamWasFinishedId;
/* it's for stream version */ break;
len = -1; }
break;
}
if (rep0 > nowPos
#ifdef _LZMA_OUT_READ
+ globalPos || rep0 > dictionarySize
#endif
)
{
return LZMA_RESULT_DATA_ERROR;
} }
len += kMatchMinLen; len += kMatchMinLen;
#ifdef _LZMA_OUT_READ
if (rep0 > distanceLimit)
#else
if (rep0 > nowPos)
#endif
return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do do
{ {
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
@@ -642,17 +685,20 @@ int LzmaDecode(
#else #else
previousByte = outStream[nowPos - rep0]; previousByte = outStream[nowPos - rep0];
#endif #endif
outStream[nowPos++] = previousByte;
len--; len--;
outStream[nowPos++] = previousByte;
} }
while(len != 0 && nowPos < outSize); while(len != 0 && nowPos < outSize);
} }
} }
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
vs->RangeDecoder = rd; vs->Range = rd.Range;
vs->Code = rd.Code;
vs->DictionaryPos = dictionaryPos; vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + nowPos; vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0; vs->Reps[0] = rep0;
vs->Reps[1] = rep1; vs->Reps[1] = rep1;
vs->Reps[2] = rep2; vs->Reps[2] = rep2;
@@ -662,6 +708,12 @@ int LzmaDecode(
vs->TempDictionary[0] = tempDictionary[0]; vs->TempDictionary[0] = tempDictionary[0];
#endif #endif
#ifdef _LZMA_IN_CB
vs->Buffer = rd.Buffer;
vs->BufferLim = rd.BufferLim;
#else
*inSizeProcessed = (SizeT)(rd.Buffer - inStream);
#endif
*outSizeProcessed = nowPos; *outSizeProcessed = nowPos;
return LZMA_RESULT_OK; return LZMA_RESULT_OK;
} }

View File

@@ -0,0 +1,521 @@
/*
LzmaStateDecode.c
LZMA Decoder (State version)
LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaStateDecode.h"
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }}
#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
{ UpdateBit0(p); mi <<= 1; A0; } else \
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ int i = numLevels; res = 1; \
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
res -= (1 << numLevels); }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
/* kRequiredInBufferSize = number of required input bytes for worst case:
longest match with longest distance.
kLzmaInBufferSize must be larger than kRequiredInBufferSize
23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE)
*/
#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8)
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
return LZMA_RESULT_OK;
}
}
int LzmaDecode(
CLzmaDecoderState *vs,
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
int finishDecoding)
{
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
unsigned char *Buffer = vs->Buffer;
int BufferSize = vs->BufferSize; /* don't change it to unsigned int */
CProb *p = vs->Probs;
int state = vs->State;
unsigned char previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
SizeT nowPos = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
unsigned char *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
unsigned char tempDictionary[4];
(*inSizeProcessed) = 0;
(*outSizeProcessed) = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
while (inSize > 0 && BufferSize < kLzmaInBufferSize)
{
Buffer[BufferSize++] = *inStream++;
(*inSizeProcessed)++;
inSize--;
}
if (BufferSize < 5)
{
vs->BufferSize = BufferSize;
return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK;
}
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
RC_INIT;
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
while(1)
{
int bufferPos = (int)(Buffer - vs->Buffer);
if (BufferSize - bufferPos < kRequiredInBufferSize)
{
int i;
BufferSize -= bufferPos;
if (BufferSize < 0)
return LZMA_RESULT_DATA_ERROR;
for (i = 0; i < BufferSize; i++)
vs->Buffer[i] = Buffer[i];
Buffer = vs->Buffer;
while (inSize > 0 && BufferSize < kLzmaInBufferSize)
{
Buffer[BufferSize++] = *inStream++;
(*inSizeProcessed)++;
inSize--;
}
if (BufferSize < kRequiredInBufferSize && !finishDecoding)
break;
}
if (nowPos >= outSize)
break;
{
CProb *prob;
UInt32 bound;
int posState = (int)((nowPos + globalPos) & posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
int symbol = 1;
UpdateBit0(prob)
prob = p + Literal + (LZMA_LIT_SIZE *
((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
int matchByte;
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
do
{
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
}
while (symbol < 0x100);
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (unsigned char)symbol;
outStream[nowPos++] = previousByte;
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob)
{
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob)
{
UpdateBit0(prob);
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
UInt32 pos;
UpdateBit0(prob);
if (distanceLimit == 0)
return LZMA_RESULT_DATA_ERROR;
if (distanceLimit < dictionarySize)
distanceLimit++;
state = state < kNumLitStates ? 9 : 11;
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
outStream[nowPos++] = previousByte;
continue;
}
else
{
UpdateBit1(prob);
}
}
else
{
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep1;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep2;
}
else
{
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
if (rep0 > distanceLimit)
return LZMA_RESULT_DATA_ERROR;
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
do
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
}
RC_NORMALIZE;
BufferSize -= (int)(Buffer - vs->Buffer);
if (BufferSize < 0)
return LZMA_RESULT_DATA_ERROR;
{
int i;
for (i = 0; i < BufferSize; i++)
vs->Buffer[i] = Buffer[i];
}
vs->BufferSize = BufferSize;
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = (UInt32)(globalPos + nowPos);
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
(*outSizeProcessed) = nowPos;
return LZMA_RESULT_OK;
}

View File

@@ -0,0 +1,115 @@
/*
LzmaStateDecode.h
LZMA Decoder interface (State version)
LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMASTATEDECODE_H
#define __LZMASTATEDECODE_H
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
/* #define _LZMA_SYSTEM_SIZE_T */
/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/
#ifndef UInt32
#ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long
#else
#define UInt32 unsigned int
#endif
#endif
#ifndef SizeT
#ifdef _LZMA_SYSTEM_SIZE_T
#include <stddef.h>
#define SizeT size_t
#else
#define SizeT UInt32
#endif
#endif
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb unsigned short
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties
{
int lc;
int lp;
int pb;
UInt32 DictionarySize;
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp)))
#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
unsigned char *Dictionary;
unsigned char Buffer[kLzmaInBufferSize];
int BufferSize;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen; /* -2: decoder needs internal initialization
-1: stream was finished,
0: ok
> 0: need to write RemainLen bytes as match Reps[0],
*/
unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */
} CLzmaDecoderState;
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; }
/* LzmaDecode: decoding from input stream to output stream.
If finishDecoding != 0, then there are no more bytes in input stream
after inStream[inSize - 1]. */
int LzmaDecode(CLzmaDecoderState *vs,
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
int finishDecoding);
#endif

View File

@@ -0,0 +1,190 @@
/*
LzmaStateTest.c
Test application for LZMA Decoder (State version)
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.21 (2005-06-08)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LzmaStateDecode.h"
const char *kCantReadMessage = "Can not read input file";
const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
#define kInBufferSize (1 << 15)
#define kOutBufferSize (1 << 15)
unsigned char g_InBuffer[kInBufferSize];
unsigned char g_OutBuffer[kOutBufferSize];
size_t MyReadFile(FILE *file, void *data, size_t size)
{ return fread(data, 1, size, file); }
int MyReadFileAndCheck(FILE *file, void *data, size_t size)
{ return (MyReadFile(file, data, size) == size); }
int PrintError(char *buffer, const char *message)
{
sprintf(buffer + strlen(buffer), "\nError: ");
sprintf(buffer + strlen(buffer), message);
return 1;
}
int main3(FILE *inFile, FILE *outFile, char *rs)
{
/* We use two 32-bit integers to construct 64-bit integer for file size.
You can remove outSizeHigh, if you don't need >= 4GB supporting,
or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
UInt32 outSize = 0;
UInt32 outSizeHigh = 0;
int waitEOS = 1;
/* waitEOS = 1, if there is no uncompressed size in headers,
so decoder will wait EOS (End of Stream Marker) in compressed stream */
int i;
int res = 0;
CLzmaDecoderState state; /* it's about 140 bytes structure, if int is 32-bit */
unsigned char properties[LZMA_PROPERTIES_SIZE];
SizeT inAvail = 0;
unsigned char *inBuffer = 0;
if (sizeof(UInt32) < 4)
return PrintError(rs, "LZMA decoder needs correct UInt32");
/* Read LZMA properties for compressed stream */
if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
return PrintError(rs, kCantReadMessage);
/* Read uncompressed size */
for (i = 0; i < 8; i++)
{
unsigned char b;
if (!MyReadFileAndCheck(inFile, &b, 1))
return PrintError(rs, kCantReadMessage);
if (b != 0xFF)
waitEOS = 0;
if (i < 4)
outSize += (UInt32)(b) << (i * 8);
else
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
}
/* Decode LZMA properties and allocate memory */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return PrintError(rs, "Incorrect stream properties");
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return PrintError(rs, kCantAllocateMessage);
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
if (state.Dictionary == 0)
{
free(state.Probs);
return PrintError(rs, kCantAllocateMessage);
}
/* Decompress */
LzmaDecoderInit(&state);
do
{
SizeT inProcessed, outProcessed;
int finishDecoding;
UInt32 outAvail = kOutBufferSize;
if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
outAvail = outSize;
if (inAvail == 0)
{
inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize);
inBuffer = g_InBuffer;
}
finishDecoding = (inAvail == 0);
res = LzmaDecode(&state,
inBuffer, inAvail, &inProcessed,
g_OutBuffer, outAvail, &outProcessed,
finishDecoding);
if (res != 0)
{
sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
break;
}
inAvail -= inProcessed;
inBuffer += inProcessed;
if (outFile != 0)
if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed)
{
PrintError(rs, kCantWriteMessage);
res = 1;
break;
}
if (outSize < outProcessed)
outSizeHigh--;
outSize -= (UInt32)outProcessed;
outSize &= 0xFFFFFFFF;
if (outProcessed == 0 && finishDecoding)
{
if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
res = 1;
break;
}
}
while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
free(state.Dictionary);
free(state.Probs);
return res;
}
int main2(int numArgs, const char *args[], char *rs)
{
FILE *inFile = 0;
FILE *outFile = 0;
int res;
sprintf(rs + strlen(rs), "\nLZMA Decoder 4.21 Copyright (c) 1999-2005 Igor Pavlov 2005-06-08\n");
if (numArgs < 2 || numArgs > 3)
{
sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
return 1;
}
inFile = fopen(args[1], "rb");
if (inFile == 0)
return PrintError(rs, "Can not open input file");
if (numArgs > 2)
{
outFile = fopen(args[2], "wb+");
if (outFile == 0)
return PrintError(rs, "Can not open output file");
}
res = main3(inFile, outFile, rs);
if (outFile != 0)
fclose(outFile);
fclose(inFile);
return res;
}
int main(int numArgs, const char *args[])
{
char rs[800] = { 0 };
int res = main2(numArgs, args, rs);
printf(rs);
return res;
}

View File

@@ -1,7 +1,9 @@
/* /*
LzmaTest.c LzmaTest.c
Test application for LZMA Decoder Test application for LZMA Decoder
LZMA SDK 4.16 Copyright (c) 1999-2004 Igor Pavlov (2005-03-18)
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.22 (2005-06-10)
*/ */
#include <stdio.h> #include <stdio.h>
@@ -10,231 +12,314 @@ LZMA SDK 4.16 Copyright (c) 1999-2004 Igor Pavlov (2005-03-18)
#include "LzmaDecode.h" #include "LzmaDecode.h"
const char *kCantReadMessage = "Can not read input file";
const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
size_t MyReadFile(FILE *file, void *data, size_t size) size_t MyReadFile(FILE *file, void *data, size_t size)
{ { return fread(data, 1, size, file); }
return (fread(data, 1, size, file) == size);
} int MyReadFileAndCheck(FILE *file, void *data, size_t size)
{ return (MyReadFile(file, data, size) == size);}
size_t MyWriteFile(FILE *file, const void *data, size_t size)
{ return fwrite(data, 1, size, file); }
int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
{ return (MyWriteFile(file, data, size) == size); }
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
#define kInBufferSize (1 << 15)
typedef struct _CBuffer typedef struct _CBuffer
{ {
ILzmaInCallback InCallback; ILzmaInCallback InCallback;
unsigned char *Buffer; FILE *File;
unsigned int Size; unsigned char Buffer[kInBufferSize];
} CBuffer; } CBuffer;
int LzmaReadCompressed(void *object, unsigned char **buffer, unsigned int *size) int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
{ {
CBuffer *bo = (CBuffer *)object; CBuffer *b = (CBuffer *)object;
*size = bo->Size; /* You can specify any available size here */ *buffer = b->Buffer;
*buffer = bo->Buffer; *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize);
bo->Buffer += *size;
bo->Size -= *size;
return LZMA_RESULT_OK; return LZMA_RESULT_OK;
} }
CBuffer g_InBuffer;
#endif #endif
int main2(int numargs, const char *args[], char *rs) #ifdef _LZMA_OUT_READ
#define kOutBufferSize (1 << 15)
unsigned char g_OutBuffer[kOutBufferSize];
#endif
int PrintError(char *buffer, const char *message)
{ {
FILE *inputHandle, *outputHandle; sprintf(buffer + strlen(buffer), "\nError: ");
unsigned int length, processedSize; sprintf(buffer + strlen(buffer), message);
unsigned int compressedSize, outSize, outSizeProcessed, lzmaInternalSize; return 1;
void *inStream, *outStream, *lzmaInternalData; }
unsigned char properties[5];
unsigned char prop0; int main3(FILE *inFile, FILE *outFile, char *rs)
int ii; {
int lc, lp, pb; /* We use two 32-bit integers to construct 64-bit integer for file size.
int res; You can remove outSizeHigh, if you don't need >= 4GB supporting,
#ifdef _LZMA_IN_CB or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
CBuffer bo; UInt32 outSize = 0;
UInt32 outSizeHigh = 0;
#ifndef _LZMA_OUT_READ
SizeT outSizeFull;
unsigned char *outStream;
#endif #endif
sprintf(rs + strlen(rs), "\nLZMA Decoder 4.16 Copyright (c) 1999-2005 Igor Pavlov 2005-03-18\n");
if (numargs < 2 || numargs > 3)
{
sprintf(rs + strlen(rs), "\nUsage: lzmaDec file.lzma [outFile]\n");
return 1;
}
inputHandle = fopen(args[1], "rb");
if (inputHandle == 0)
{
sprintf(rs + strlen(rs), "\n Open input file error");
return 1;
}
fseek(inputHandle, 0, SEEK_END);
length = ftell(inputHandle);
fseek(inputHandle, 0, SEEK_SET);
if (!MyReadFile(inputHandle, properties, sizeof(properties)))
return 1;
outSize = 0; int waitEOS = 1;
for (ii = 0; ii < 4; ii++) /* waitEOS = 1, if there is no uncompressed size in headers,
{ so decoder will wait EOS (End of Stream Marker) in compressed stream */
unsigned char b;
if (!MyReadFile(inputHandle, &b, sizeof(b)))
return 1;
outSize += (unsigned int)(b) << (ii * 8);
}
if (outSize == 0xFFFFFFFF) #ifndef _LZMA_IN_CB
{ SizeT compressedSize;
sprintf(rs + strlen(rs), "\nstream version is not supported"); unsigned char *inStream;
return 1;
}
for (ii = 0; ii < 4; ii++)
{
unsigned char b;
if (!MyReadFile(inputHandle, &b, sizeof(b)))
return 1;
if (b != 0)
{
sprintf(rs + strlen(rs), "\n too long file");
return 1;
}
}
compressedSize = length - 13;
inStream = malloc(compressedSize);
if (inStream == 0)
{
sprintf(rs + strlen(rs), "\n can't allocate");
return 1;
}
if (!MyReadFile(inputHandle, inStream, compressedSize))
{
sprintf(rs + strlen(rs), "\n can't read");
return 1;
}
fclose(inputHandle);
prop0 = properties[0];
if (prop0 >= (9*5*5))
{
sprintf(rs + strlen(rs), "\n Properties error");
return 1;
}
for (pb = 0; prop0 >= (9 * 5);
pb++, prop0 -= (9 * 5));
for (lp = 0; prop0 >= 9;
lp++, prop0 -= 9);
lc = prop0;
lzmaInternalSize =
(LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb);
#ifdef _LZMA_OUT_READ
lzmaInternalSize += 100;
#endif #endif
outStream = malloc(outSize); CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
lzmaInternalData = malloc(lzmaInternalSize); unsigned char properties[LZMA_PROPERTIES_SIZE];
if (outStream == 0 || lzmaInternalData == 0)
{ int res;
sprintf(rs + strlen(rs), "\n can't allocate");
return 1;
}
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
bo.InCallback.Read = LzmaReadCompressed; g_InBuffer.File = inFile;
bo.Buffer = (unsigned char *)inStream; #endif
bo.Size = compressedSize;
if (sizeof(UInt32) < 4)
return PrintError(rs, "LZMA decoder needs correct UInt32");
#ifndef _LZMA_IN_CB
{
long length;
fseek(inFile, 0, SEEK_END);
length = ftell(inFile);
fseek(inFile, 0, SEEK_SET);
if ((long)(SizeT)length != length)
return PrintError(rs, "Too big compressed stream");
compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
}
#endif
/* Read LZMA properties for compressed stream */
if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
return PrintError(rs, kCantReadMessage);
/* Read uncompressed size */
{
int i;
for (i = 0; i < 8; i++)
{
unsigned char b;
if (!MyReadFileAndCheck(inFile, &b, 1))
return PrintError(rs, kCantReadMessage);
if (b != 0xFF)
waitEOS = 0;
if (i < 4)
outSize += (UInt32)(b) << (i * 8);
else
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
}
#ifndef _LZMA_OUT_READ
if (waitEOS)
return PrintError(rs, "Stream with EOS marker is not supported");
outSizeFull = (SizeT)outSize;
if (sizeof(SizeT) >= 8)
outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
return PrintError(rs, "Too big uncompressed stream");
#endif
}
/* Decode LZMA properties and allocate memory */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return PrintError(rs, "Incorrect stream properties");
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
#ifdef _LZMA_OUT_READ
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
#else
outStream = (unsigned char *)malloc(outSizeFull);
#endif
#ifndef _LZMA_IN_CB
inStream = (unsigned char *)malloc(compressedSize);
#endif
if (state.Probs == 0
#ifdef _LZMA_OUT_READ
|| state.Dictionary == 0
#else
|| outStream == 0
#endif
#ifndef _LZMA_IN_CB
|| inStream == 0
#endif
)
{
free(state.Probs);
#ifdef _LZMA_OUT_READ
free(state.Dictionary);
#else
free(outStream);
#endif
#ifndef _LZMA_IN_CB
free(inStream);
#endif
return PrintError(rs, kCantAllocateMessage);
}
/* Decompress */
#ifdef _LZMA_IN_CB
g_InBuffer.InCallback.Read = LzmaReadCompressed;
#else
if (!MyReadFileAndCheck(inFile, inStream, compressedSize))
return PrintError(rs, kCantReadMessage);
#endif #endif
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
{ {
UInt32 nowPos; #ifndef _LZMA_IN_CB
unsigned char *dictionary; SizeT inAvail = compressedSize;
UInt32 dictionarySize = 0; const unsigned char *inBuffer = inStream;
int i; #endif
for (i = 0; i < 4; i++) LzmaDecoderInit(&state);
dictionarySize += (UInt32)(properties[1 + i]) << (i * 8); do
if (dictionarySize == 0)
dictionarySize = 1; /* LZMA decoder can not work with dictionarySize = 0 */
dictionary = (unsigned char *)malloc(dictionarySize);
if (dictionary == 0)
{ {
sprintf(rs + strlen(rs), "\n can't allocate"); #ifndef _LZMA_IN_CB
return 1; SizeT inProcessed;
} #endif
res = LzmaDecoderInit((unsigned char *)lzmaInternalData, lzmaInternalSize, SizeT outProcessed;
lc, lp, pb, SizeT outAvail = kOutBufferSize;
dictionary, dictionarySize, if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
outAvail = (SizeT)outSize;
res = LzmaDecode(&state,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
&bo.InCallback &g_InBuffer.InCallback,
#else #else
(unsigned char *)inStream, compressedSize inBuffer, inAvail, &inProcessed,
#endif #endif
); g_OutBuffer, outAvail, &outProcessed);
if (res == 0)
for (nowPos = 0; nowPos < outSize;)
{
UInt32 blockSize = outSize - nowPos;
UInt32 kBlockSize = 0x10000;
if (blockSize > kBlockSize)
blockSize = kBlockSize;
res = LzmaDecode((unsigned char *)lzmaInternalData,
((unsigned char *)outStream) + nowPos, blockSize, &outSizeProcessed);
if (res != 0) if (res != 0)
break;
if (outSizeProcessed == 0)
{ {
outSize = nowPos; sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
break;
}
#ifndef _LZMA_IN_CB
inAvail -= inProcessed;
inBuffer += inProcessed;
#endif
if (outFile != 0)
if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed))
{
PrintError(rs, kCantWriteMessage);
res = 1;
break;
}
if (outSize < outProcessed)
outSizeHigh--;
outSize -= (UInt32)outProcessed;
outSize &= 0xFFFFFFFF;
if (outProcessed == 0)
{
if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
res = 1;
break; break;
} }
nowPos += outSizeProcessed;
} }
free(dictionary); while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
} }
#else #else
res = LzmaDecode((unsigned char *)lzmaInternalData, lzmaInternalSize, {
lc, lp, pb, #ifndef _LZMA_IN_CB
SizeT inProcessed;
#endif
SizeT outProcessed;
res = LzmaDecode(&state,
#ifdef _LZMA_IN_CB #ifdef _LZMA_IN_CB
&bo.InCallback, &g_InBuffer.InCallback,
#else #else
(unsigned char *)inStream, compressedSize, inStream, compressedSize, &inProcessed,
#endif #endif
(unsigned char *)outStream, outSize, &outSizeProcessed); outStream, outSizeFull, &outProcessed);
outSize = outSizeProcessed; if (res != 0)
{
sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
}
else if (outFile != 0)
{
if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed))
{
PrintError(rs, kCantWriteMessage);
res = 1;
}
}
}
#endif #endif
if (res != 0) free(state.Probs);
#ifdef _LZMA_OUT_READ
free(state.Dictionary);
#else
free(outStream);
#endif
#ifndef _LZMA_IN_CB
free(inStream);
#endif
return res;
}
int main2(int numArgs, const char *args[], char *rs)
{
FILE *inFile = 0;
FILE *outFile = 0;
int res;
sprintf(rs + strlen(rs), "\nLZMA Decoder 4.21 Copyright (c) 1999-2005 Igor Pavlov 2005-06-08\n");
if (numArgs < 2 || numArgs > 3)
{ {
sprintf(rs + strlen(rs), "\nerror = %d\n", res); sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
return 1; return 1;
} }
if (numargs > 2) inFile = fopen(args[1], "rb");
if (inFile == 0)
return PrintError(rs, "Can not open input file");
if (numArgs > 2)
{ {
outputHandle = fopen(args[2], "wb+"); outFile = fopen(args[2], "wb+");
if (outputHandle == 0) if (outFile == 0)
{ return PrintError(rs, "Can not open output file");
sprintf(rs + strlen(rs), "\n Open output file error");
return 1;
}
processedSize = fwrite(outStream, 1, outSize, outputHandle);
if (processedSize != outSize)
{
sprintf(rs + strlen(rs), "\n can't write");
return 1;
}
fclose(outputHandle);
} }
free(lzmaInternalData);
free(outStream); res = main3(inFile, outFile, rs);
free(inStream);
return 0; if (outFile != 0)
fclose(outFile);
fclose(inFile);
return res;
} }
int main(int numargs, const char *args[]) int main(int numArgs, const char *args[])
{ {
char sz[800] = { 0 }; char rs[800] = { 0 };
int code = main2(numargs, args, sz); int res = main2(numArgs, args, rs);
printf(sz); printf(rs);
return code; return res;
} }

View File

@@ -16,7 +16,6 @@
#include "Resource/CopyDialog/CopyDialog.h" #include "Resource/CopyDialog/CopyDialog.h"
#include "ExtractCallback.h" #include "ExtractCallback.h"
#include "UpdateCallback100.h"
#include "ViewSettings.h" #include "ViewSettings.h"
#include "RegistryUtils.h" #include "RegistryUtils.h"
@@ -27,6 +26,8 @@ using namespace NFind;
extern DWORD g_ComCtl32Version; extern DWORD g_ComCtl32Version;
extern HINSTANCE g_hInstance; extern HINSTANCE g_hInstance;
static LPCWSTR kTempDirPrefix = L"7zE";
void CPanelCallbackImp::OnTab() void CPanelCallbackImp::OnTab()
{ {
if (g_App.NumPanels != 1) if (g_App.NumPanels != 1)
@@ -42,8 +43,8 @@ void CPanelCallbackImp::SetFocusToPath(int index)
} }
void CPanelCallbackImp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame) void CPanelCallbackImp::OnCopy(bool move, bool copyToSame)
{ _app->OnCopy(externalNames, move, copyToSame, _index); } { _app->OnCopy(move, copyToSame, _index); }
void CPanelCallbackImp::OnSetSameFolder() void CPanelCallbackImp::OnSetSameFolder()
{ _app->OnSetSameFolder(_index); } { _app->OnSetSameFolder(_index); }
@@ -52,9 +53,13 @@ void CPanelCallbackImp::OnSetSubFolder()
{ _app->OnSetSubFolder(_index); } { _app->OnSetSubFolder(_index); }
void CPanelCallbackImp::PanelWasFocused() void CPanelCallbackImp::PanelWasFocused()
{ { _app->SetFocusedPanel(_index); }
_app->LastFocusedPanel = _index;
} void CPanelCallbackImp::DragBegin()
{ _app->DragBegin(_index); }
void CPanelCallbackImp::DragEnd()
{ _app->DragEnd(); }
void CApp::SetListSettings() void CApp::SetListSettings()
{ {
@@ -350,6 +355,7 @@ void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2])
Panels[i]._xSize = xSizes[0] + xSizes[1]; Panels[i]._xSize = xSizes[0] + xSizes[1];
CreateOnePanel(i, (i == LastFocusedPanel) ? mainPath : L""); CreateOnePanel(i, (i == LastFocusedPanel) ? mainPath : L"");
} }
SetFocusedPanel(LastFocusedPanel);
Panels[LastFocusedPanel].SetFocusToList(); Panels[LastFocusedPanel].SetFocusToList();
} }
@@ -398,111 +404,55 @@ void CApp::Release()
Panels[i].Release(); Panels[i].Release();
} }
class CWindowDisable static bool IsThereFolderOfPath(const UString &path)
{ {
bool _wasEnabled; CFileInfoW fileInfo;
CWindow _window; if (!FindFile(path, fileInfo))
public: return false;
CWindowDisable(HWND window): _window(window) return fileInfo.IsDirectory();
{ }
_wasEnabled = _window.IsEnabled();
if (_wasEnabled)
_window.Enable(false);
}
~CWindowDisable()
{
if (_wasEnabled)
_window.Enable(true);
}
};
struct CThreadExtract // reduces path to part that exists on disk
static void ReducePathToRealFileSystemPath(UString &path)
{ {
bool Move; while(!path.IsEmpty())
CMyComPtr<IFolderOperations> FolderOperations;
CRecordVector<UINT32> Indices;
UString DestPath;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
HRESULT Result;
DWORD Extract()
{ {
NCOM::CComInitializer comInitializer; if (IsThereFolderOfPath(path))
ExtractCallbackSpec->ProgressDialog.WaitCreating();
if (Move)
{ {
Result = FolderOperations->MoveTo( NName::NormalizeDirPathPrefix(path);
&Indices.Front(), Indices.Size(), break;
DestPath, ExtractCallback);
// ExtractCallbackSpec->DestroyWindows();
} }
int pos = path.ReverseFind('\\');
if (pos < 0)
path.Empty();
else else
{ {
Result = FolderOperations->CopyTo( path = path.Left(pos + 1);
&Indices.Front(), Indices.Size(), if (path.Length() == 3 && path[1] == L':')
DestPath, ExtractCallback); break;
// ExtractCallbackSpec->DestroyWindows(); path = path.Left(pos);
} }
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
} }
}
static DWORD WINAPI MyThreadFunction(void *param) // return true for dir\, if dir exist
{ static bool CheckFolderPath(const UString &path)
return ((CThreadExtract *)param)->Extract();
}
};
struct CThreadUpdate
{ {
bool Move; UString pathReduced = path;
CMyComPtr<IFolderOperations> FolderOperations; ReducePathToRealFileSystemPath(pathReduced);
UString SrcFolderPrefix; return (pathReduced == path);
UStringVector FileNames; }
CRecordVector<const wchar_t *> FileNamePointers;
CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
CUpdateCallback100Imp *UpdateCallbackSpec;
HRESULT Result;
DWORD Process()
{
NCOM::CComInitializer comInitializer;
UpdateCallbackSpec->ProgressDialog.WaitCreating();
if (Move)
{
{
throw 1;
// srcPanel.MessageBoxMyError(L"Move is not supported");
return 0;
}
}
else
{
Result = FolderOperations->CopyFrom(
SrcFolderPrefix,
&FileNamePointers.Front(),
FileNamePointers.Size(),
UpdateCallback);
}
UpdateCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param) static bool IsPathAbsolute(const UString &path)
{
return ((CThreadUpdate *)param)->Process();
}
};
void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int srcPanelIndex)
{ {
bool external = (externalNames.Size() > 0); if ((path.Length() >= 1 && path[0] == L'\\') ||
if (external) (path.Length() >= 3 && path[1] == L':' && path[2] == L'\\'))
copyToSame = true; return true;
return false;
}
void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
{
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &srcPanel = Panels[srcPanelIndex]; CPanel &srcPanel = Panels[srcPanelIndex];
CPanel &destPanel = Panels[destPanelIndex]; CPanel &destPanel = Panels[destPanelIndex];
@@ -510,220 +460,162 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int
CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel);
CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel);
bool useSrcPanel = true; if (!srcPanel.DoesItSupportOperations())
if (!external) {
if (NumPanels != 1) srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
{ return;
if (!srcPanel.IsFSFolder() && !destPanel.IsFSFolder()) }
{
srcPanel.MessageBox(LangLoadStringW(IDS_CANNOT_COPY, 0x03020207));
return;
}
useSrcPanel = copyToSame || destPanel.IsFSFolder();
if (move && !useSrcPanel)
{
srcPanel.MessageBoxMyError(L"Move is not supported");
return;
}
}
CPanel &panel = useSrcPanel ? srcPanel : destPanel; CRecordVector<UInt32> indices;
CMyComPtr<IFolderOperations> folderOperations;
// if (move)
if (panel._folder.QueryInterface(IID_IFolderOperations,
&folderOperations) != S_OK)
{
panel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
return;
}
CRecordVector<UINT32> indices;
UString destPath; UString destPath;
bool useDestPanel = false;
if (external)
{ {
UString message = L"Are you sure you want to copy files to archive \'"; if (copyToSame)
message += srcPanel._currentFolderPrefix;
message += L"\'?";
int res = MessageBoxW(_window, message, L"Confirm File Copy",
MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL);
if (res != IDYES)
return;
}
else
{
CCopyDialog copyDialog;
UStringVector copyFolders;
ReadCopyHistory(copyFolders);
int i;
for (i = 0; i < copyFolders.Size(); i++)
copyDialog.Strings.Add(GetSystemString(copyFolders[i]));
if (copyToSame)
{
int focusedItem = srcPanel._listView.GetFocusedItem();
if (focusedItem < 0)
return;
int realIndex = srcPanel.GetRealItemIndex(focusedItem);
if (realIndex == -1)
return;
indices.Add(realIndex);
copyDialog.Value = srcPanel.GetItemName(realIndex);
}
else
{
srcPanel.GetOperatedItemIndices(indices);
if (indices.Size() == 0)
return;
UString destPath = destPanel._currentFolderPrefix;
if (NumPanels == 1)
{ {
while(!destPath.IsEmpty()) int focusedItem = srcPanel._listView.GetFocusedItem();
{ if (focusedItem < 0)
CFileInfoW fileInfo; return;
if (FindFile(destPath, fileInfo)) int realIndex = srcPanel.GetRealItemIndex(focusedItem);
{ if (realIndex == -1)
if (fileInfo.IsDirectory()) return;
{ indices.Add(realIndex);
destPath += L'\\'; destPath = srcPanel.GetItemName(realIndex);
break;
}
}
int pos = destPath.ReverseFind('\\');
if (pos < 0)
destPath.Empty();
else
{
destPath = destPath.Left(pos + 1);
if (destPath.Length() == 3 && destPath[1] == L':')
break;
destPath = destPath.Left(pos);
}
}
}
copyDialog.Value = destPath;
}
copyDialog.Title = move ?
LangLoadStringW(IDS_MOVE, 0x03020202):
LangLoadStringW(IDS_COPY, 0x03020201);
copyDialog.Static = move ?
LangLoadStringW(IDS_MOVE_TO, 0x03020204):
LangLoadStringW(IDS_COPY_TO, 0x03020203);
if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
return;
AddUniqueStringToHeadOfList(copyFolders, GetUnicodeString(
copyDialog.Value));
while (copyFolders.Size() > 20)
copyFolders.DeleteBack();
SaveCopyHistory(copyFolders);
/// ?????
SetCurrentDirectory(GetSystemString(srcPanel._currentFolderPrefix));
if (!NDirectory::MyGetFullPathName(copyDialog.Value, destPath))
{
srcPanel.MessageBoxLastError();
return;
}
if (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1)
NDirectory::CreateComplexDirectory(destPath);
}
UString title = move ?
LangLoadStringW(IDS_MOVING, 0x03020206):
LangLoadStringW(IDS_COPYING, 0x03020205);
UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
CSelectedState srcSelState;
CSelectedState destSelState;
if (copyToSame || move)
srcPanel.SaveSelectedState(srcSelState);
if (!copyToSame)
destPanel.SaveSelectedState(destSelState);
HRESULT result;
if (useSrcPanel && !external)
{
CThreadExtract extracter;
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.ExtractCallbackSpec->ParentWindow = _window;
extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = _window;
extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
extracter.ExtractCallbackSpec->Init();
extracter.Move = move;
extracter.FolderOperations = folderOperations;
extracter.Indices = indices;;
extracter.DestPath = GetUnicodeString(destPath);
CThread thread;
if (!thread.Create(CThreadExtract::MyThreadFunction, &extracter))
throw 271824;
extracter.ExtractCallbackSpec->StartProgressDialog(title);
result = extracter.Result;
}
else
{
CThreadUpdate updater;
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
updater.UpdateCallback = updater.UpdateCallbackSpec;
updater.UpdateCallbackSpec->ProgressDialog.MainWindow = _window;
updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" ");
updater.UpdateCallbackSpec->Init(_window, false, L"");
updater.Move = move;
updater.FolderOperations = folderOperations;
if (external)
{
updater.FileNames.Reserve(externalNames.Size());
for(int i = 0; i < externalNames.Size(); i++)
updater.FileNames.Add(externalNames[i]);
} }
else else
{ {
updater.SrcFolderPrefix = srcPanel._currentFolderPrefix; srcPanel.GetOperatedItemIndices(indices);
updater.FileNames.Reserve(indices.Size()); if (indices.Size() == 0)
for(int i = 0; i < indices.Size(); i++) return;
updater.FileNames.Add(srcPanel.GetItemName(indices[i])); destPath = destPanel._currentFolderPrefix;
if (NumPanels == 1)
ReducePathToRealFileSystemPath(destPath);
} }
updater.FileNamePointers.Reserve(updater.FileNames.Size());
int i; CCopyDialog copyDialog;
for(i = 0; i < updater.FileNames.Size(); i++) UStringVector copyFolders;
updater.FileNamePointers.Add(updater.FileNames[i]); ReadCopyHistory(copyFolders);
CThread thread;
if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater)) copyDialog.Strings = copyFolders;
throw 271824; copyDialog.Value = destPath;
updater.UpdateCallbackSpec->StartProgressDialog(title);
result = updater.Result; copyDialog.Title = move ?
LangLoadStringW(IDS_MOVE, 0x03020202):
LangLoadStringW(IDS_COPY, 0x03020201);
copyDialog.Static = move ?
LangLoadStringW(IDS_MOVE_TO, 0x03020204):
LangLoadStringW(IDS_COPY_TO, 0x03020203);
if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
return;
destPath = copyDialog.Value;
if (!IsPathAbsolute(destPath))
{
if (!srcPanel.IsFSFolder())
{
srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
return;
}
destPath = srcPanel._currentFolderPrefix + destPath;
}
if (indices.Size() > 1 || (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1) ||
IsThereFolderOfPath(destPath))
{
NDirectory::CreateComplexDirectory(destPath);
NName::NormalizeDirPathPrefix(destPath);
if (!CheckFolderPath(destPath))
{
if (NumPanels < 2 || destPath != destPanel._currentFolderPrefix || !destPanel.DoesItSupportOperations())
{
srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
return;
}
useDestPanel = true;
}
}
else
{
int pos = destPath.ReverseFind('\\');
if (pos >= 0)
{
UString prefix = destPath.Left(pos + 1);
NDirectory::CreateComplexDirectory(prefix);
if (!CheckFolderPath(prefix))
{
srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
return;
}
}
}
AddUniqueStringToHeadOfList(copyFolders, destPath);
while (copyFolders.Size() > 20)
copyFolders.DeleteBack();
SaveCopyHistory(copyFolders);
} }
/* bool useSrcPanel = (!useDestPanel || !srcPanel.IsFSFolder() || destPanel.IsFSFolder());
if (useSrcPanel) bool useTemp = useSrcPanel && useDestPanel;
extractCallbackSpec->DestroyWindows(); NFile::NDirectory::CTempDirectoryW tempDirectory;
*/ UString tempDirPrefix;
if (useTemp)
if (result != S_OK)
{ {
disableTimerProcessing1.Restore(); tempDirectory.Create(kTempDirPrefix);
disableTimerProcessing2.Restore(); tempDirPrefix = tempDirectory.GetPath();
// For Password: NFile::NName::NormalizeDirPathPrefix(tempDirPrefix);
srcPanel.SetFocusToList();
if (result != E_ABORT)
srcPanel.MessageBoxError(result, L"Error");
return;
} }
CSelectedState srcSelState;
CSelectedState destSelState;
srcPanel.SaveSelectedState(srcSelState);
destPanel.SaveSelectedState(destSelState);
HRESULT result;
if (useSrcPanel)
{
UString folder = useTemp ? tempDirPrefix : destPath;
result = srcPanel.CopyTo(indices, folder, move, true, 0);
if (result != S_OK)
{
disableTimerProcessing1.Restore();
disableTimerProcessing2.Restore();
// For Password:
srcPanel.SetFocusToList();
if (result != E_ABORT)
srcPanel.MessageBoxError(result, L"Error");
return;
}
}
if (useDestPanel)
{
UStringVector filePaths;
UString folderPrefix;
if (useTemp)
folderPrefix = tempDirPrefix;
else
folderPrefix = srcPanel._currentFolderPrefix;
filePaths.Reserve(indices.Size());
for(int i = 0; i < indices.Size(); i++)
filePaths.Add(srcPanel.GetItemName(indices[i]));
result = destPanel.CopyFrom(folderPrefix, filePaths, true, 0);
if (result != S_OK)
{
disableTimerProcessing1.Restore();
disableTimerProcessing2.Restore();
// For Password:
srcPanel.SetFocusToList();
if (result != E_ABORT)
srcPanel.MessageBoxError(result, L"Error");
return;
}
}
if (copyToSame || move) if (copyToSame || move)
{ {
srcPanel.RefreshListCtrl(srcSelState); srcPanel.RefreshListCtrl(srcSelState);
@@ -738,7 +630,6 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int
srcPanel.SetFocusToList(); srcPanel.SetFocusToList();
} }
void CApp::OnSetSameFolder(int srcPanelIndex) void CApp::OnSetSameFolder(int srcPanelIndex)
{ {
if (NumPanels <= 1) if (NumPanels <= 1)

View File

@@ -35,16 +35,69 @@ public:
} }
virtual void OnTab(); virtual void OnTab();
virtual void SetFocusToPath(int index); virtual void SetFocusToPath(int index);
virtual void OnCopy(UStringVector &externalNames, bool move, bool copyToSame); virtual void OnCopy(bool move, bool copyToSame);
virtual void OnSetSameFolder(); virtual void OnSetSameFolder();
virtual void OnSetSubFolder(); virtual void OnSetSubFolder();
virtual void PanelWasFocused(); virtual void PanelWasFocused();
virtual void DragBegin();
virtual void DragEnd();
}; };
class CApp;
class CDropTarget:
public IDropTarget,
public CMyUnknownImp
{
CMyComPtr<IDataObject> m_DataObject;
int m_SelectionIndex;
bool m_DropIsAllowed; // = true, if data contain fillist
bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel.
// check it only if m_DropIsAllowed == true
int m_SubFolderIndex;
UString m_SubFolderName;
CPanel *m_Panel;
bool m_IsAppTarget; // true, if we want to drop to app window (not to panel).
void QueryGetData(IDataObject *dataObject);
bool IsFsFolderPath() const;
DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect);
void RemoveSelection();
void PositionCursor(POINTL ptl);
UString GetTargetPath() const;
bool SetPath(bool enablePath) const;
bool SetPath();
public:
MY_UNKNOWN_IMP1_MT(IDropTarget)
STDMETHOD(DragEnter)(IDataObject * dataObject, DWORD keyState,
POINTL pt, DWORD *effect);
STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD * effect);
STDMETHOD(DragLeave)();
STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState,
POINTL pt, DWORD *effect);
CDropTarget():
TargetPanelIndex(-1),
SrcPanelIndex(-1),
m_IsAppTarget(false),
m_Panel(0),
App(0),
m_PanelDropIsAllowed(false),
m_DropIsAllowed(false),
m_SelectionIndex(-1),
m_SubFolderIndex(-1) {}
CApp *App;
int SrcPanelIndex; // index of D&D source_panel
int TargetPanelIndex; // what panel to use as target_panel of Application
};
class CApp class CApp
{ {
NWindows::CWindow _window;
public: public:
NWindows::CWindow _window;
bool ShowSystemMenu; bool ShowSystemMenu;
int NumPanels; int NumPanels;
int LastFocusedPanel; int LastFocusedPanel;
@@ -65,9 +118,37 @@ public:
NWindows::NControl::CReBar _rebar; NWindows::NControl::CReBar _rebar;
NWindows::NControl::CToolBar _archiveToolBar; NWindows::NControl::CToolBar _archiveToolBar;
NWindows::NControl::CToolBar _standardToolBar; NWindows::NControl::CToolBar _standardToolBar;
CDropTarget *_dropTargetSpec;
CMyComPtr<IDropTarget> _dropTarget;
void CreateDragTarget()
{
_dropTargetSpec = new CDropTarget();
_dropTarget = _dropTargetSpec;
_dropTargetSpec->App = (this);
}
void SetFocusedPanel(int index)
{
LastFocusedPanel = index;
_dropTargetSpec->TargetPanelIndex = LastFocusedPanel;
}
void DragBegin(int panelIndex)
{
_dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex;
_dropTargetSpec->SrcPanelIndex = panelIndex;
}
void DragEnd()
{
_dropTargetSpec->TargetPanelIndex = LastFocusedPanel;
_dropTargetSpec->SrcPanelIndex = -1;
}
void OnCopy(UStringVector &externalNames, void OnCopy(bool move, bool copyToSame, int srcPanelIndex);
bool move, bool copyToSame, int srcPanelIndex);
void OnSetSameFolder(int srcPanelIndex); void OnSetSameFolder(int srcPanelIndex);
void OnSetSubFolder(int srcPanelIndex); void OnSetSubFolder(int srcPanelIndex);
@@ -87,6 +168,8 @@ public:
int GetFocusedPanelIndex() const { return LastFocusedPanel; } int GetFocusedPanelIndex() const { return LastFocusedPanel; }
bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); }
/* /*
void SetCurrentIndex() void SetCurrentIndex()
{ CurrentPanel = GetFocusedPanelIndex(); } { CurrentPanel = GetFocusedPanelIndex(); }
@@ -108,9 +191,9 @@ public:
void Rename() void Rename()
{ GetFocusedPanel().RenameFile(); } { GetFocusedPanel().RenameFile(); }
void CopyTo() void CopyTo()
{ OnCopy(UStringVector(), false, false, GetFocusedPanelIndex()); } { OnCopy(false, false, GetFocusedPanelIndex()); }
void MoveTo() void MoveTo()
{ OnCopy(UStringVector(), true, false, GetFocusedPanelIndex()); } { OnCopy(true, false, GetFocusedPanelIndex()); }
void Delete() void Delete()
{ GetFocusedPanel().DeleteItems(); } { GetFocusedPanel().DeleteItems(); }
void Split(); void Split();

View File

@@ -2,28 +2,14 @@
#include "StdAfx.h" #include "StdAfx.h"
// #define INITGUID
#include <initguid.h> #include <initguid.h>
#include "IFolder.h" #include "IFolder.h"
#include "../IPassword.h" #include "../IPassword.h"
// #include "../Archiver/Format/Common/ArchiveInterface.h"
#include "PluginInterface.h" #include "PluginInterface.h"
#include "ExtractCallback.h" #include "ExtractCallback.h"
#include "../ICoder.h" #include "../ICoder.h"
/*
// {23170F69-40C1-278A-1000-000100030000}
DEFINE_GUID(CLSID_CAgentArchiveHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
*/
// {23170F69-40C1-278A-1000-000100020000} // {23170F69-40C1-278A-1000-000100020000}
DEFINE_GUID(CLSID_CZipContextMenu, DEFINE_GUID(CLSID_CZipContextMenu,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
/*
// {23170F69-40C1-278F-1000-000110050000}
DEFINE_GUID(CLSID_CTest,
0x23170F69, 0x40C1, 0x278F, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
*/

View File

@@ -0,0 +1,108 @@
// EnumFormatEtc.cpp
#include "StdAfx.h"
#include "EnumFormatEtc.h"
#include "MyCom2.h"
class CEnumFormatEtc :
public IEnumFORMATETC,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1_MT(IEnumFORMATETC)
STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
STDMETHOD(Skip)(ULONG celt);
STDMETHOD(Reset)(void);
STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats);
~CEnumFormatEtc();
private:
LONG m_RefCount;
ULONG m_NumFormats;
FORMATETC *m_Formats;
ULONG m_Index;
};
static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src)
{
*dest = *src;
if(src->ptd)
{
dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
*(dest->ptd) = *(src->ptd);
}
}
CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats)
{
m_RefCount = 1;
m_Index = 0;
m_NumFormats = 0;
m_Formats = new FORMATETC[numFormats];
if(m_Formats)
{
m_NumFormats = numFormats;
for(int i = 0; i < numFormats; i++)
DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]);
}
}
CEnumFormatEtc::~CEnumFormatEtc()
{
if(m_Formats)
{
for(ULONG i = 0; i < m_NumFormats; i++)
if(m_Formats[i].ptd)
CoTaskMemFree(m_Formats[i].ptd);
delete[]m_Formats;
}
}
STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
{
ULONG copied = 0;
if(celt == 0 || pFormatEtc == 0)
return E_INVALIDARG;
while(m_Index < m_NumFormats && copied < celt)
{
DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]);
copied++;
m_Index++;
}
if(pceltFetched != 0)
*pceltFetched = copied;
return (copied == celt) ? S_OK : S_FALSE;
}
STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt)
{
m_Index += celt;
return (m_Index <= m_NumFormats) ? S_OK : S_FALSE;
}
STDMETHODIMP CEnumFormatEtc::Reset(void)
{
m_Index = 0;
return S_OK;
}
STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc)
{
HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc);
if(hResult == S_OK)
((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index;
return hResult;
}
// replacement for SHCreateStdEnumFmtEtc
HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat)
{
if(numFormats == 0 || formats == 0 || enumFormat == 0)
return E_INVALIDARG;
*enumFormat = new CEnumFormatEtc(formats, numFormats);
return (*enumFormat) ? S_OK : E_OUTOFMEMORY;
}

View File

@@ -0,0 +1,10 @@
// EnumFormatEtc.h
#ifndef __ENUMFORMATETC_H
#define __ENUMFORMATETC_H
#include <windows.h>
HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat);
#endif

View File

@@ -27,7 +27,7 @@ using namespace NFind;
CExtractCallbackImp::~CExtractCallbackImp() CExtractCallbackImp::~CExtractCallbackImp()
{ {
if (!Messages.IsEmpty()) if (ShowMessages && !Messages.IsEmpty())
{ {
CMessagesDialog messagesDialog; CMessagesDialog messagesDialog;
messagesDialog.Messages = &Messages; messagesDialog.Messages = &Messages;
@@ -43,7 +43,7 @@ void CExtractCallbackImp::Init()
void CExtractCallbackImp::AddErrorMessage(LPCWSTR message) void CExtractCallbackImp::AddErrorMessage(LPCWSTR message)
{ {
Messages.Add(GetSystemString(message)); Messages.Add(message);
} }
STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total)

View File

@@ -95,7 +95,8 @@ private:
void AddErrorMessage(LPCWSTR message); void AddErrorMessage(LPCWSTR message);
public: public:
CProgressDialog ProgressDialog; CProgressDialog ProgressDialog;
CSysStringVector Messages; UStringVector Messages;
bool ShowMessages;
HWND ParentWindow; HWND ParentWindow;
INT_PTR StartProgressDialog(const UString &title) INT_PTR StartProgressDialog(const UString &title)
{ {
@@ -114,7 +115,8 @@ public:
PasswordIsDefined(false), PasswordIsDefined(false),
#endif #endif
OverwriteMode(NExtract::NOverwriteMode::kAskBefore), OverwriteMode(NExtract::NOverwriteMode::kAskBefore),
ParentWindow(0) ParentWindow(0),
ShowMessages(true)
{} {}
~CExtractCallbackImp(); ~CExtractCallbackImp();

View File

@@ -304,7 +304,10 @@ int WINAPI WinMain( HINSTANCE hInstance,
g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
NCOM::CComInitializer comInitializer; // OleInitialize is required for drag and drop.
OleInitialize(NULL);
// Maybe needs CoInitializeEx also ?
// NCOM::CComInitializer comInitializer;
UString programString, commandsString; UString programString, commandsString;
// MessageBoxW(0, GetCommandLineW(), L"", 0); // MessageBoxW(0, GetCommandLineW(), L"", 0);
@@ -343,6 +346,7 @@ int WINAPI WinMain( HINSTANCE hInstance,
} }
g_HWND = 0; g_HWND = 0;
OleUninitialize();
return msg.wParam; return msg.wParam;
} }
@@ -459,15 +463,22 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
xSizes[1] = xSize - kSplitterWidth - xSizes[0]; xSizes[1] = xSize - kSplitterWidth - xSizes[0];
if (xSizes[1] < 0) if (xSizes[1] < 0)
xSizes[1] = 0; xSizes[1] = 0;
g_App.CreateDragTarget();
g_App.Create(hWnd, g_MainPath, xSizes); g_App.Create(hWnd, g_MainPath, xSizes);
// g_SplitterPos = 0; // g_SplitterPos = 0;
DragAcceptFiles(hWnd, TRUE); // ::DragAcceptFiles(hWnd, TRUE);
RegisterDragDrop(hWnd, g_App._dropTarget);
break; break;
} }
case WM_DESTROY: case WM_DESTROY:
{ {
::DragAcceptFiles(hWnd, FALSE); // ::DragAcceptFiles(hWnd, FALSE);
RevokeDragDrop(hWnd);
g_App._dropTarget.Release();
g_App.Save(); g_App.Save();
g_App.Release(); g_App.Release();
SaveWindowInfo(hWnd); SaveWindowInfo(hWnd);
@@ -559,11 +570,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
g_App.OnNotify(wParam, (LPNMHDR)lParam); g_App.OnNotify(wParam, (LPNMHDR)lParam);
break; break;
} }
/*
case WM_DROPFILES: case WM_DROPFILES:
{ {
g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam); g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam);
return 0 ; return 0 ;
} }
*/
} }
return DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam);
} }

View File

@@ -319,6 +319,14 @@ SOURCE=.\AppState.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\EnumFormatEtc.cpp
# End Source File
# Begin Source File
SOURCE=.\EnumFormatEtc.h
# End Source File
# Begin Source File
SOURCE=.\FileFolderPluginOpen.cpp SOURCE=.\FileFolderPluginOpen.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -335,6 +343,14 @@ SOURCE=.\Panel.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\PanelCopy.cpp
# End Source File
# Begin Source File
SOURCE=.\PanelDrag.cpp
# End Source File
# Begin Source File
SOURCE=.\PanelFolderChange.cpp SOURCE=.\PanelFolderChange.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -788,6 +804,14 @@ SOURCE=..\..\Windows\Handle.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Windows\Memory.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Windows\Memory.h
# End Source File
# Begin Source File
SOURCE=..\..\Windows\Menu.h SOURCE=..\..\Windows\Menu.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1126,6 +1150,10 @@ SOURCE=.\Move2.bmp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\MyCom2.h
# End Source File
# Begin Source File
SOURCE=.\MyLoadMenu.cpp SOURCE=.\MyLoadMenu.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

42
7zip/FileManager/MyCom2.h Executable file
View File

@@ -0,0 +1,42 @@
// MyCom2.h
#ifndef __MYCOM2_H
#define __MYCOM2_H
#include "Common/MyCom.h"
#define MY_ADDREF_RELEASE_MT \
STDMETHOD_(ULONG, AddRef)() { InterlockedIncrement((LONG *)&__m_RefCount); return __m_RefCount; } \
STDMETHOD_(ULONG, Release)() { InterlockedDecrement((LONG *)&__m_RefCount); if (__m_RefCount != 0) \
return __m_RefCount; delete this; return 0; }
#define MY_UNKNOWN_IMP_SPEC_MT(i) \
MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY(IUnknown) \
i \
MY_QUERYINTERFACE_END \
MY_ADDREF_RELEASE_MT
#define MY_UNKNOWN_IMP_SPEC_MT2(i1, i) \
MY_QUERYINTERFACE_BEGIN \
if (iid == IID_IUnknown) \
{ *outObject = (void *)(IUnknown *)(i1 *)this; AddRef(); return S_OK; } i \
MY_QUERYINTERFACE_END \
MY_ADDREF_RELEASE_MT
#define MY_UNKNOWN_IMP_MT MY_UNKNOWN_IMP_SPEC_MT(;)
#define MY_UNKNOWN_IMP1_MT(i) MY_UNKNOWN_IMP_SPEC_MT2( \
i, \
MY_QUERYINTERFACE_ENTRY(i) \
)
#define MY_UNKNOWN_IMP2_MT(i1, i2) MY_UNKNOWN_IMP_SPEC_MT2( \
i1, \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
)
#endif

View File

@@ -8,7 +8,6 @@
#include "Common/StringConvert.h" #include "Common/StringConvert.h"
#include "Windows/Error.h" #include "Windows/Error.h"
#include "Windows/PropVariant.h" #include "Windows/PropVariant.h"
#include "Windows/Shell.h"
#include "../PropID.h" #include "../PropID.h"
@@ -60,6 +59,7 @@ LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
_processTimer = true; _processTimer = true;
_processNotify = true; _processNotify = true;
_panelCallback = panelCallback; _panelCallback = panelCallback;
_appState = appState; _appState = appState;
// _index = index; // _index = index;
@@ -107,9 +107,11 @@ LRESULT CPanel::OnMessage(UINT message, UINT wParam, LPARAM lParam)
if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)))
return 0; return 0;
break; break;
/*
case WM_DROPFILES: case WM_DROPFILES:
CompressDropFiles(HDROP(wParam)); CompressDropFiles(HDROP(wParam));
return 0; return 0;
*/
} }
return CWindow2::OnMessage(message, wParam, lParam); return CWindow2::OnMessage(message, wParam, lParam);
} }
@@ -488,13 +490,12 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct)
// InitListCtrl(); // InitListCtrl();
RefreshListCtrl(); RefreshListCtrl();
RefreshStatusBar(); RefreshStatusBar();
::DragAcceptFiles(HWND(*this), TRUE);
return true; return true;
} }
void CPanel::OnDestroy() void CPanel::OnDestroy()
{ {
::DragAcceptFiles(HWND(*this), FALSE);
SaveListViewInfo(); SaveListViewInfo();
CWindow2::OnDestroy(); CWindow2::OnDestroy();
} }
@@ -651,6 +652,17 @@ bool CPanel::IsFSFolder() const
return (GetFolderTypeID() == L"FSFolder"); return (GetFolderTypeID() == L"FSFolder");
} }
bool CPanel::IsFSDrivesFolder() const
{
return (GetFolderTypeID() == L"FSDrives");
}
bool CPanel::DoesItSupportOperations() const
{
CMyComPtr<IFolderOperations> folderOperations;
return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK;
}
void CPanel::SetListViewMode(UINT32 index) void CPanel::SetListViewMode(UINT32 index)
{ {
if (index >= 4) if (index >= 4)
@@ -668,37 +680,6 @@ void CPanel::RefreshStatusBar()
PostMessage(kRefreshStatusBar); PostMessage(kRefreshStatusBar);
} }
void CPanel::CompressDropFiles(HDROP dr)
{
NShell::CDrop drop(true);
drop.Attach(dr);
CSysStringVector fileNames;
drop.QueryFileNames(fileNames);
if (fileNames.Size() == 0)
return;
UStringVector fileNamesUnicode;
for (int i = 0; i < fileNames.Size(); i++)
fileNamesUnicode.Add(GetUnicodeString(fileNames[i]));
const UString archiveName = CreateArchiveName(
fileNamesUnicode.Front(), (fileNamesUnicode.Size() > 1), false);
UString currentDirectory;
if (IsFSFolder())
{
CompressFiles(_currentFolderPrefix, archiveName, fileNamesUnicode,
false, // email
true // showDialog
);
}
else
{
_panelCallback->OnCopy(fileNamesUnicode, false, true);
/*
if (!NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), currentDirectory))
return;
*/
}
}
void CPanel::AddToArchive() void CPanel::AddToArchive()
{ {
CRecordVector<UINT32> indices; CRecordVector<UINT32> indices;
@@ -722,7 +703,7 @@ void CPanel::AddToArchive()
const UString archiveName = CreateArchiveName( const UString archiveName = CreateArchiveName(
names.Front(), (names.Size() > 1), false); names.Front(), (names.Size() > 1), false);
CompressFiles(_currentFolderPrefix, archiveName, CompressFiles(_currentFolderPrefix, archiveName,
names, false, true); names, false, true, false);
KillSelection(); KillSelection();
} }
@@ -730,7 +711,7 @@ void CPanel::ExtractArchives()
{ {
if (_parentFolders.Size() > 0) if (_parentFolders.Size() > 0)
{ {
_panelCallback->OnCopy(UStringVector(), false, false); _panelCallback->OnCopy(false, false);
return; return;
} }
CRecordVector<UINT32> indices; CRecordVector<UINT32> indices;

View File

@@ -3,6 +3,14 @@
#ifndef __PANEL_H #ifndef __PANEL_H
#define __PANEL_H #define __PANEL_H
#include "Common/MyCom.h"
#include "Windows/DLL.h"
#include "Windows/FileFind.h"
#include "Windows/FileDir.h"
#include "Windows/Synchronization.h"
#include "Windows/Handle.h"
#include "Windows/Control/ToolBar.h" #include "Windows/Control/ToolBar.h"
#include "Windows/Control/ReBar.h" #include "Windows/Control/ReBar.h"
#include "Windows/Control/ListView.h" #include "Windows/Control/ListView.h"
@@ -12,21 +20,11 @@
#include "Windows/Control/Window2.h" #include "Windows/Control/Window2.h"
#include "Windows/Control/StatusBar.h" #include "Windows/Control/StatusBar.h"
#include "Windows/DLL.h"
#include "Windows/FileFind.h"
#include "Windows/FileDir.h"
#include "Windows/Synchronization.h"
#include "Windows/Handle.h"
#include "Common/MyCom.h"
#include "SysIconUtils.h" #include "SysIconUtils.h"
#include "IFolder.h" #include "IFolder.h"
#include "ViewSettings.h" #include "ViewSettings.h"
#include "AppState.h" #include "AppState.h"
#include "MyCom2.h"
const int kParentFolderID = 100; const int kParentFolderID = 100;
const int kPluginMenuStartID = 1000; const int kPluginMenuStartID = 1000;
@@ -37,10 +35,12 @@ class CPanelCallback
public: public:
virtual void OnTab() = 0; virtual void OnTab() = 0;
virtual void SetFocusToPath(int index) = 0; virtual void SetFocusToPath(int index) = 0;
virtual void OnCopy(UStringVector &externalNames, bool move, bool copyToSame) = 0; virtual void OnCopy(bool move, bool copyToSame) = 0;
virtual void OnSetSameFolder() = 0; virtual void OnSetSameFolder() = 0;
virtual void OnSetSubFolder() = 0; virtual void OnSetSubFolder() = 0;
virtual void PanelWasFocused() = 0; virtual void PanelWasFocused() = 0;
virtual void DragBegin() = 0;
virtual void DragEnd() = 0;
}; };
void PanelCopyItems(); void PanelCopyItems();
@@ -76,13 +76,13 @@ public:
struct CTempFileInfo struct CTempFileInfo
{ {
UString ItemName; UString ItemName;
CSysString FolderPath; UString FolderPath;
CSysString FilePath; UString FilePath;
NWindows::NFile::NFind::CFileInfo FileInfo; NWindows::NFile::NFind::CFileInfoW FileInfo;
void DeleteDirAndFile() void DeleteDirAndFile()
{ {
NWindows::NFile::NDirectory::DeleteFileAlways(FilePath); NWindows::NFile::NDirectory::DeleteFileAlways(FilePath);
::RemoveDirectory(FolderPath); NWindows::NFile::NDirectory::MyRemoveDirectory(FolderPath);
} }
}; };
@@ -90,7 +90,6 @@ struct CFolderLink: public CTempFileInfo
{ {
NWindows::NDLL::CLibrary Library; NWindows::NDLL::CLibrary Library;
CMyComPtr<IFolderFolder> ParentFolder; CMyComPtr<IFolderFolder> ParentFolder;
// CSysString RealPath;
}; };
enum MyMessages enum MyMessages
@@ -144,7 +143,6 @@ class CPanel:public NWindows::NControl::CWindow2
HWND _mainWindow; HWND _mainWindow;
CExtToIconMap _extToIconMap; CExtToIconMap _extToIconMap;
// int _index;
UINT _baseID; UINT _baseID;
int _comboBoxID; int _comboBoxID;
UINT _statusBarID; UINT _statusBarID;
@@ -162,7 +160,7 @@ class CPanel:public NWindows::NControl::CWindow2
bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result); bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result);
bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result); bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result);
bool OnNotifyList(LPNMHDR lParam, LRESULT &result); bool OnNotifyList(LPNMHDR lParam, LRESULT &result);
// void OnDrag(LPNMLISTVIEW nmListView); void OnDrag(LPNMLISTVIEW nmListView);
bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result); bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result);
BOOL OnBeginLabelEdit(LV_DISPINFO * lpnmh); BOOL OnBeginLabelEdit(LV_DISPINFO * lpnmh);
BOOL OnEndLabelEdit(LV_DISPINFO * lpnmh); BOOL OnEndLabelEdit(LV_DISPINFO * lpnmh);
@@ -176,8 +174,6 @@ public:
void CreateFolder(); void CreateFolder();
void CreateFile(); void CreateFile();
// void Split();
private: private:
void ChangeWindowSize(int xSize, int ySize); void ChangeWindowSize(int xSize, int ySize);
@@ -222,8 +218,8 @@ public:
bool _showDots; bool _showDots;
bool _showRealFileIcons; bool _showRealFileIcons;
// bool _virtualMode; // bool _virtualMode;
// CUIntVector _realIndices;
CBoolVector _selectedStatusVector; CBoolVector _selectedStatusVector;
CUIntVector _realIndices;
UInt32 GetRealIndex(const LVITEM &item) const UInt32 GetRealIndex(const LVITEM &item) const
{ {
@@ -375,11 +371,15 @@ public:
void GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const; void GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const;
void GetOperatedItemIndices(CRecordVector<UInt32> &indices) const; void GetOperatedItemIndices(CRecordVector<UInt32> &indices) const;
// void GetOperatedListViewIndices(CRecordVector<UInt32> &indices) const;
void KillSelection(); void KillSelection();
UString GetFolderTypeID() const; UString GetFolderTypeID() const;
bool IsRootFolder() const; bool IsRootFolder() const;
bool IsFSFolder() const; bool IsFSFolder() const;
bool IsFSDrivesFolder() const;
bool DoesItSupportOperations() const;
bool _processTimer; bool _processTimer;
bool _processNotify; bool _processNotify;
@@ -430,14 +430,13 @@ public:
void OpenFolder(int index); void OpenFolder(int index);
HRESULT OpenParentArchiveFolder(); HRESULT OpenParentArchiveFolder();
HRESULT OpenItemAsArchive(const UString &name, HRESULT OpenItemAsArchive(const UString &name,
const CSysString &folderPath, const UString &folderPath,
const CSysString &filePath); const UString &filePath);
HRESULT OpenItemAsArchive(const UString &aName); HRESULT OpenItemAsArchive(const UString &aName);
HRESULT OpenItemAsArchive(int index); HRESULT OpenItemAsArchive(int index);
// void OpenItem(int index, CSysString realPath);
void OpenItemInArchive(int index, bool tryInternal, bool tryExternal, void OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
bool editMode); bool editMode);
LRESULT OnOpenItemChanged(const CSysString &folderPath, const UString &itemName); LRESULT OnOpenItemChanged(const UString &folderPath, const UString &itemName);
LRESULT OnOpenItemChanged(LPARAM lParam); LRESULT OnOpenItemChanged(LPARAM lParam);
void OpenItem(int index, bool tryInternal, bool tryExternal); void OpenItem(int index, bool tryInternal, bool tryExternal);
@@ -453,11 +452,23 @@ public:
void RefreshStatusBar(); void RefreshStatusBar();
void OnRefreshStatusBar(); void OnRefreshStatusBar();
void CompressDropFiles(HDROP dr);
void AddToArchive(); void AddToArchive();
void ExtractArchives(); void ExtractArchives();
void TestArchives(); void TestArchives();
HRESULT CopyTo(const CRecordVector<UInt32> &indices, const UString &folder,
bool moveMode, bool showErrorMessages, UStringVector *messages);
HRESULT CopyFrom(const UString &folderPrefix, const UStringVector &filePaths,
bool showErrorMessages, UStringVector *messages);
void CopyFrom(const UStringVector &filePaths);
// empty folderPath means create new Archive to path of first fileName.
void DropObject(IDataObject * dataObject, const UString &folderPath);
// empty folderPath means create new Archive to path of first fileName.
void CompressDropFiles(const UStringVector &fileNames, const UString &folderPath);
}; };
#endif #endif

View File

@@ -1,10 +1,209 @@
// PanelCopy.cpp // PanelExtract.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include "App.h" #include "Windows/COM.h"
void CApp::PanelCopyItems() #include "Panel.h"
#include "resource.h"
#include "LangUtils.h"
#include "ExtractCallback.h"
#include "Windows/Thread.h"
////////////////////////////////////////////////////////////////
#include "..\UI\Resource\Extract\resource.h"
#include "UpdateCallback100.h"
using namespace NWindows;
struct CThreadExtractInArchive2
{ {
return; CMyComPtr<IFolderOperations> FolderOperations;
} CRecordVector<UInt32> Indices;
UString DestPath;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
HRESULT Result;
bool MoveMode;
CThreadExtractInArchive2(): MoveMode(false) {}
DWORD Extract()
{
// NCOM::CComInitializer comInitializer;
ExtractCallbackSpec->ProgressDialog.WaitCreating();
if (MoveMode)
Result = FolderOperations->MoveTo(&Indices.Front(), Indices.Size(),
DestPath, ExtractCallback);
else
Result = FolderOperations->CopyTo(&Indices.Front(), Indices.Size(),
DestPath, ExtractCallback);
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadExtractInArchive2 *)param)->Extract();
}
};
HRESULT CPanel::CopyTo(const CRecordVector<UInt32> &indices, const UString &folder,
bool moveMode, bool showErrorMessages, UStringVector *messages)
{
CMyComPtr<IFolderOperations> folderOperations;
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
{
UString errorMessage = LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
if (showErrorMessages)
MessageBox(errorMessage);
else if (messages != 0)
messages->Add(errorMessage);
return E_FAIL;
}
CThreadExtractInArchive2 extracter;
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.ExtractCallbackSpec->ParentWindow = GetParent();
extracter.ExtractCallbackSpec->ShowMessages = showErrorMessages;
UString title = moveMode ?
LangLoadStringW(IDS_MOVING, 0x03020206):
LangLoadStringW(IDS_COPYING, 0x03020205);
UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent();
extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
extracter.ExtractCallbackSpec->Init();
extracter.Indices = indices;
extracter.DestPath = folder;
extracter.FolderOperations = folderOperations;
extracter.MoveMode = moveMode;
CThread extractThread;
if (!extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter))
throw 271824;
extracter.ExtractCallbackSpec->StartProgressDialog(title);
if (messages != 0)
*messages = extracter.ExtractCallbackSpec->Messages;
return extracter.Result;
}
struct CThreadUpdate
{
CMyComPtr<IFolderOperations> FolderOperations;
UString FolderPrefix;
UStringVector FileNames;
CRecordVector<const wchar_t *> FileNamePointers;
CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
CUpdateCallback100Imp *UpdateCallbackSpec;
HRESULT Result;
DWORD Process()
{
NCOM::CComInitializer comInitializer;
UpdateCallbackSpec->ProgressDialog.WaitCreating();
Result = FolderOperations->CopyFrom(
FolderPrefix,
&FileNamePointers.Front(),
FileNamePointers.Size(),
UpdateCallback);
UpdateCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadUpdate *)param)->Process();
}
};
HRESULT CPanel::CopyFrom(const UString &folderPrefix, const UStringVector &filePaths,
bool showErrorMessages, UStringVector *messages)
{
CMyComPtr<IFolderOperations> folderOperations;
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
{
UString errorMessage = LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
if (showErrorMessages)
MessageBox(errorMessage);
else if (messages != 0)
messages->Add(errorMessage);
return E_FAIL;
}
CThreadUpdate updater;
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
updater.UpdateCallback = updater.UpdateCallbackSpec;
UString title = LangLoadStringW(IDS_COPYING, 0x03020205);
UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
updater.UpdateCallbackSpec->ProgressDialog.MainWindow = GetParent();
updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" ");
updater.UpdateCallbackSpec->Init((HWND)*this, false, L"");
updater.FolderOperations = folderOperations;
updater.FolderPrefix = folderPrefix;
updater.FileNames.Reserve(filePaths.Size());
int i;
for(i = 0; i < filePaths.Size(); i++)
updater.FileNames.Add(filePaths[i]);
updater.FileNamePointers.Reserve(updater.FileNames.Size());
for(i = 0; i < updater.FileNames.Size(); i++)
updater.FileNamePointers.Add(updater.FileNames[i]);
CThread thread;
if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater))
throw 271824;
updater.UpdateCallbackSpec->StartProgressDialog(title);
if (messages != 0)
*messages = updater.UpdateCallbackSpec->Messages;
return updater.Result;
}
void CPanel::CopyFrom(const UStringVector &filePaths)
{
UString message = L"Are you sure you want to copy files to archive\n\'";
message += _currentFolderPrefix;
message += L"\' ?";
int res = ::MessageBoxW(*(this), message, L"Confirm File Copy",
MB_YESNOCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL);
if (res != IDYES)
return;
CDisableTimerProcessing disableTimerProcessing(*this);
CSelectedState srcSelState;
SaveSelectedState(srcSelState);
HRESULT result = CopyFrom(L"", filePaths, true, 0);
if (result != S_OK)
{
disableTimerProcessing.Restore();
// For Password:
SetFocusToList();
if (result != E_ABORT)
MessageBoxError(result, L"Error");
return;
}
RefreshListCtrl(srcSelState);
disableTimerProcessing.Restore();
SetFocusToList();
}

704
7zip/FileManager/PanelDrag.cpp Executable file
View File

@@ -0,0 +1,704 @@
// PanelDrag.cpp
#include "StdAfx.h"
#include "Windows/Memory.h"
#include "Windows/FileDir.h"
#include "Windows/Shell.h"
#include "Common/StringConvert.h"
#include "../UI/Common/ArchiveName.h"
#include "../UI/Common/CompressCall.h"
#include "Resource/MessagesDialog/MessagesDialog.h"
using namespace NWindows;
#include "App.h"
#include "EnumFormatEtc.h"
static wchar_t *kTempDirPrefix = L"7zE";
static LPCTSTR kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder");
////////////////////////////////////////////////////////
class CDataObject:
public IDataObject,
public CMyUnknownImp
{
private:
FORMATETC m_Etc;
UINT m_SetFolderFormat;
public:
MY_UNKNOWN_IMP1_MT(IDataObject)
STDMETHODIMP GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM medium);
STDMETHODIMP GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM medium);
STDMETHODIMP QueryGetData(LPFORMATETC pformatetc );
STDMETHODIMP GetCanonicalFormatEtc ( LPFORMATETC pformatetc, LPFORMATETC pformatetcOut)
{ pformatetcOut->ptd = NULL; return ResultFromScode(E_NOTIMPL); }
STDMETHODIMP SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release);
STDMETHODIMP EnumFormatEtc(DWORD drection, LPENUMFORMATETC *enumFormatEtc);
STDMETHODIMP DAdvise(FORMATETC *etc, DWORD advf, LPADVISESINK pAdvSink, DWORD *pdwConnection)
{ return OLE_E_ADVISENOTSUPPORTED; }
STDMETHODIMP DUnadvise(DWORD dwConnection) { return OLE_E_ADVISENOTSUPPORTED; }
STDMETHODIMP EnumDAdvise( LPENUMSTATDATA *ppenumAdvise) { return OLE_E_ADVISENOTSUPPORTED; }
CDataObject();
NMemory::CGlobal hGlobal;
UString Path;
};
CDataObject::CDataObject()
{
m_SetFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat);
m_Etc.cfFormat = CF_HDROP;
m_Etc.ptd = NULL;
m_Etc.dwAspect = DVASPECT_CONTENT;
m_Etc.lindex = -1;
m_Etc.tymed = TYMED_HGLOBAL;
}
STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release)
{
if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL &&
etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL)
{
Path.Empty();
if (medium->hGlobal == 0)
return S_OK;
size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t);
const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal);
if (src != 0)
{
for (size_t i = 0; i < size; i++)
{
wchar_t c = src[i];
if (c == 0)
break;
Path += c;
}
GlobalUnlock(medium->hGlobal);
return S_OK;
}
}
return E_NOTIMPL;
}
static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal)
{
SIZE_T size = GlobalSize(srcGlobal);
const void *src = GlobalLock(srcGlobal);
if (src == 0)
return 0;
HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size);
if (destGlobal != 0)
{
void *dest = GlobalLock(destGlobal);
if (dest == 0)
{
GlobalFree(destGlobal);
destGlobal = 0;
}
else
{
memcpy(dest, src, size);
GlobalUnlock(destGlobal);
}
}
GlobalUnlock(srcGlobal);
return destGlobal;
}
STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium)
{
RINOK(QueryGetData(etc));
medium->tymed = m_Etc.tymed;
medium->pUnkForRelease = 0;
medium->hGlobal = DuplicateGlobalMem(hGlobal);
if (medium->hGlobal == 0)
return E_OUTOFMEMORY;
return S_OK;
}
STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC etc, LPSTGMEDIUM medium)
{
// Seems Windows doesn't call it, so we will not implement it.
return E_UNEXPECTED;
}
STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC etc)
{
if ((m_Etc.tymed & etc->tymed) &&
m_Etc.cfFormat == etc->cfFormat &&
m_Etc.dwAspect == etc->dwAspect)
return S_OK;
return DV_E_FORMATETC;
}
STDMETHODIMP CDataObject::EnumFormatEtc(DWORD direction, LPENUMFORMATETC FAR* enumFormatEtc)
{
if(direction != DATADIR_GET)
return E_NOTIMPL;
return CreateEnumFormatEtc(1, &m_Etc, enumFormatEtc);
}
////////////////////////////////////////////////////////
class CDropSource:
public IDropSource,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1_MT(IDropSource)
STDMETHOD(QueryContinueDrag)(BOOL escapePressed, DWORD keyState);
STDMETHOD(GiveFeedback)(DWORD effect);
bool NeedExtract;
CPanel *Panel;
CRecordVector<UInt32> Indices;
UString Folder;
CDataObject *DataObjectSpec;
CMyComPtr<IDataObject> DataObject;
bool NeedPostCopy;
HRESULT Result;
UStringVector Messages;
CDropSource(): NeedPostCopy(false), Panel(0), Result(S_OK) {}
};
STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState)
{
if(escapePressed == TRUE)
return DRAGDROP_S_CANCEL;
if((keyState & MK_LBUTTON) == 0)
{
Result = S_OK;
bool needExtract = NeedExtract;
// MoveMode = (((keyState & MK_SHIFT) != 0) && MoveIsAllowed);
if (!DataObjectSpec->Path.IsEmpty())
{
needExtract = false;
NeedPostCopy = true;
}
if (needExtract)
{
Result = Panel->CopyTo(Indices, Folder,
false, // moveMode,
false, // showMessages
&Messages);
if (Result != S_OK || !Messages.IsEmpty())
return DRAGDROP_S_CANCEL;
}
return DRAGDROP_S_DROP;
}
return S_OK;
}
STDMETHODIMP CDropSource::GiveFeedback(DWORD effect)
{
return DRAGDROP_S_USEDEFAULTCURSORS;
}
static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const CSysStringVector &names)
{
size_t totalLength = 1;
int i;
for (i = 0; i < names.Size(); i++)
totalLength += names[i].Length() + 1;
if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(TCHAR) + sizeof(DROPFILES)))
return false;
NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0)
return false;
dropFiles->fNC = FALSE;
dropFiles->pt.x = 0;
dropFiles->pt.y = 0;
dropFiles->pFiles = sizeof(DROPFILES);
#ifdef _UNICODE
dropFiles->fWide = TRUE;
#else
dropFiles->fWide = FALSE;
#endif
TCHAR *p = (TCHAR *)((BYTE *)dropFiles + sizeof(DROPFILES));
for (i = 0; i < names.Size(); i++)
{
const CSysString &s = names[i];
int fullLength = s.Length() + 1;
if (fullLength > totalLength)
return false; // error: name was changed!
lstrcpy(p, s);
p += fullLength;
totalLength -= fullLength;
}
if (totalLength == 0)
return false;
*p = 0;
return true;
}
void CPanel::OnDrag(LPNMLISTVIEW nmListView)
{
CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
if (!DoesItSupportOperations())
return;
CRecordVector<UInt32> indices;
GetOperatedItemIndices(indices);
if (indices.Size() == 0)
return;
// CSelectedState selState;
// SaveSelectedState(selState);
UString dirPrefix;
NFile::NDirectory::CTempDirectoryW tempDirectory;
bool isFSFolder = IsFSFolder();
if (isFSFolder)
dirPrefix = _currentFolderPrefix;
else
{
tempDirectory.Create(kTempDirPrefix);
dirPrefix = tempDirectory.GetPath();
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
}
CDataObject *dataObjectSpec = new CDataObject;
CMyComPtr<IDataObject> dataObject = dataObjectSpec;
{
CSysStringVector names;
for (int i = 0; i < indices.Size(); i++)
names.Add(GetSystemString(dirPrefix + GetItemName(indices[i])));
if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names))
return;
}
CDropSource *dropSourceSpec = new CDropSource;
CMyComPtr<IDropSource> dropSource = dropSourceSpec;
dropSourceSpec->NeedExtract = !isFSFolder;
dropSourceSpec->Panel = this;
dropSourceSpec->Indices = indices;
dropSourceSpec->Folder = dirPrefix;
dropSourceSpec->DataObjectSpec = dataObjectSpec;
dropSourceSpec->DataObject = dataObjectSpec;
bool moveIsAllowed = isFSFolder;
DWORD effectsOK = DROPEFFECT_COPY;
if (moveIsAllowed)
effectsOK |= DROPEFFECT_MOVE;
DWORD effect;
_panelCallback->DragBegin();
HRESULT res = DoDragDrop(dataObject, dropSource, effectsOK, &effect);
_panelCallback->DragEnd();
bool canceled = (res == DRAGDROP_S_CANCEL);
if (res == DRAGDROP_S_DROP)
{
res = dropSourceSpec->Result;
if (dropSourceSpec->NeedPostCopy)
if (!dataObjectSpec->Path.IsEmpty())
{
NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path);
res = CopyTo(indices, dataObjectSpec->Path,
(effect == DROPEFFECT_MOVE),// dropSourceSpec->MoveMode,
false, // showErrorMessages
&dropSourceSpec->Messages);
}
/*
if (effect == DROPEFFECT_MOVE)
RefreshListCtrl(selState);
*/
}
else
{
if (res != DRAGDROP_S_CANCEL && res != S_OK)
MessageBoxError(res, L"7-Zip");
res = dropSourceSpec->Result;
}
if (!dropSourceSpec->Messages.IsEmpty())
{
CMessagesDialog messagesDialog;
messagesDialog.Messages = &dropSourceSpec->Messages;
messagesDialog.Create((*this));
}
if (res != S_OK && res != E_ABORT)
MessageBoxError(res, L"7-Zip");
if (res == S_OK && dropSourceSpec->Messages.IsEmpty() && !canceled)
KillSelection();
}
void CDropTarget::QueryGetData(IDataObject *dataObject)
{
FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
m_DropIsAllowed = (dataObject->QueryGetData(&etc) == S_OK);
}
static void MySetDropHighlighted(HWND hWnd, int index, bool enable)
{
LVITEM item;
item.mask = LVIF_STATE;
item.iItem = index;
item.iSubItem = 0;
item.state = enable ? LVIS_DROPHILITED : 0;
item.stateMask = LVIS_DROPHILITED;
item.pszText = 0;
ListView_SetItem(hWnd, &item);
}
void CDropTarget::RemoveSelection()
{
if (m_SelectionIndex >= 0 && m_Panel != 0)
MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false);
m_SelectionIndex = -1;
}
void CDropTarget::PositionCursor(POINTL ptl)
{
m_SubFolderIndex = -1;
POINT pt;
pt.x = ptl.x;
pt.y = ptl.y;
RemoveSelection();
m_IsAppTarget = true;
m_Panel = NULL;
m_PanelDropIsAllowed = true;
if (!m_DropIsAllowed)
return;
{
POINT pt2 = pt;
App->_window.ScreenToClient(&pt2);
for (int i = 0; i < kNumPanelsMax; i++)
if (App->IsPanelVisible(i))
if (App->Panels[i].IsEnabled())
if (ChildWindowFromPointEx(App->_window, pt2,
CWP_SKIPINVISIBLE | CWP_SKIPDISABLED) == (HWND)App->Panels[i])
{
m_Panel = &App->Panels[i];
m_IsAppTarget = false;
if (i == SrcPanelIndex)
{
m_PanelDropIsAllowed = false;
return;
}
break;
}
if (m_IsAppTarget)
{
if (TargetPanelIndex >= 0)
m_Panel = &App->Panels[TargetPanelIndex];
return;
}
}
/*
m_PanelDropIsAllowed = m_Panel->DoesItSupportOperations();
if (!m_PanelDropIsAllowed)
return;
*/
if (!m_Panel->IsFSFolder() && !m_Panel->IsFSDrivesFolder())
return;
if (WindowFromPoint(pt) != (HWND)m_Panel->_listView)
return;
LVHITTESTINFO info;
m_Panel->_listView.ScreenToClient(&pt);
info.pt = pt;
int index = ListView_HitTest(m_Panel->_listView, &info);
if (index < 0)
return;
int realIndex = m_Panel->GetRealItemIndex(index);
if (realIndex == -1)
return;
if (!m_Panel->IsItemFolder(realIndex))
return;
m_SubFolderIndex = realIndex;
m_SubFolderName = m_Panel->GetItemName(m_SubFolderIndex);
MySetDropHighlighted(m_Panel->_listView, index, true);
m_SelectionIndex = index;
}
bool CDropTarget::IsFsFolderPath() const
{
if (!m_IsAppTarget && m_Panel != 0)
return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0));
return false;
}
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect)
{
if (!m_DropIsAllowed || !m_PanelDropIsAllowed)
return DROPEFFECT_NONE;
if (!IsFsFolderPath())
allowedEffect &= ~DROPEFFECT_MOVE;
DWORD effect = 0;
if(keyState & MK_CONTROL)
effect = allowedEffect & DROPEFFECT_COPY;
else if(keyState & MK_SHIFT)
effect = allowedEffect & DROPEFFECT_MOVE;
if(effect == 0)
{
if(allowedEffect & DROPEFFECT_COPY) effect = DROPEFFECT_COPY;
if(allowedEffect & DROPEFFECT_MOVE) effect = DROPEFFECT_MOVE;
}
if(effect == 0)
return DROPEFFECT_NONE;
return effect;
}
UString CDropTarget::GetTargetPath() const
{
if (!IsFsFolderPath())
return UString();
UString path = m_Panel->_currentFolderPrefix;
if (m_Panel->IsFSDrivesFolder())
path.Empty();
if (m_SubFolderIndex >= 0 && !m_SubFolderName.IsEmpty())
{
path += m_SubFolderName;
path += L"\\";
}
return path;
}
bool CDropTarget::SetPath(bool enablePath) const
{
UINT setFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat);
FORMATETC etc = { setFolderFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM medium;
medium.tymed = etc.tymed;
medium.pUnkForRelease = 0;
UString path;
if (enablePath)
path = GetTargetPath();
size_t size = path.Length() + 1;
medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t));
if (medium.hGlobal == 0)
return false;
wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal);
if (dest == 0)
{
GlobalUnlock(medium.hGlobal);
return false;
}
wcscpy(dest, path);
GlobalUnlock(medium.hGlobal);
bool res = m_DataObject->SetData(&etc, &medium, FALSE) == S_OK;
GlobalFree(medium.hGlobal);
return res;
}
bool CDropTarget::SetPath()
{
return SetPath(m_DropIsAllowed && m_PanelDropIsAllowed && IsFsFolderPath());
}
STDMETHODIMP CDropTarget::DragEnter(IDataObject * dataObject, DWORD keyState,
POINTL pt, DWORD *effect)
{
QueryGetData(dataObject);
m_DataObject = dataObject;
return DragOver(keyState, pt, effect);
}
STDMETHODIMP CDropTarget::DragOver(DWORD keyState, POINTL pt, DWORD *effect)
{
PositionCursor(pt);
*effect = GetEffect(keyState, pt, *effect);
SetPath();
return S_OK;
}
STDMETHODIMP CDropTarget::DragLeave()
{
RemoveSelection();
SetPath(false);
m_DataObject.Release();
return S_OK;
}
// We suppose that there was ::DragOver for same POINTL_pt before ::Drop
// So SetPath() is same as in Drop.
STDMETHODIMP CDropTarget::Drop(IDataObject *dataObject, DWORD keyState,
POINTL pt, DWORD * effect)
{
QueryGetData(dataObject);
PositionCursor(pt);
*effect = GetEffect(keyState, pt, *effect);
m_DataObject = dataObject;
if(m_DropIsAllowed && m_PanelDropIsAllowed)
{
bool needDrop = true;
if (IsFsFolderPath())
needDrop = !SetPath();
if (needDrop)
{
UString path = GetTargetPath();
if (m_IsAppTarget && m_Panel)
if (m_Panel->IsFSFolder())
path = m_Panel->_currentFolderPrefix;
m_Panel->DropObject(dataObject, path);
}
}
RemoveSelection();
m_DataObject.Release();
return S_OK;
}
static void ReadUnicodeStrings(const wchar_t *p, size_t size, UStringVector &names)
{
names.Clear();
UString name;
for (;size > 0; size--)
{
wchar_t c = *p++;
if (c == 0)
{
if (name.IsEmpty())
break;
names.Add(name);
name.Empty();
}
else
name += c;
}
}
static void ReadAnsiStrings(const char *p, size_t size, UStringVector &names)
{
names.Clear();
AString name;
for (;size > 0; size--)
{
char c = *p++;
if (c == 0)
{
if (name.IsEmpty())
break;
names.Add(GetUnicodeString(name));
name.Empty();
}
else
name += c;
}
}
void CPanel::DropObject(IDataObject *dataObject, const UString &folderPath)
{
FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM medium;
HRESULT res = dataObject->GetData(&etc, &medium);
if (res != S_OK)
return;
if (medium.tymed != TYMED_HGLOBAL)
return;
UStringVector names;
{
NMemory::CGlobal global;
global.Attach(medium.hGlobal);
size_t blockSize = GlobalSize(medium.hGlobal);
NMemory::CGlobalLock dropLock(medium.hGlobal);
const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0)
return;
if (blockSize < dropFiles->pFiles)
return;
size_t size = blockSize - dropFiles->pFiles;
const void *namesData = (const Byte *)dropFiles + dropFiles->pFiles;
if (dropFiles->fWide)
ReadUnicodeStrings((const wchar_t *)namesData, size / sizeof(wchar_t), names);
else
ReadAnsiStrings((const char *)namesData, size, names);
}
CompressDropFiles(names, folderPath);
}
/*
void CPanel::CompressDropFiles(HDROP dr)
{
CSysStringVector fileNames;
{
NShell::CDrop drop(true);
drop.Attach(dr);
drop.QueryFileNames(fileNames);
}
UStringVector fileNamesUnicode;
for (int i = 0; i < fileNames.Size(); i++)
fileNamesUnicode.Add(GetUnicodeString(fileNames[i]));
CompressDropFiles(fileNamesUnicode);
}
*/
static bool IsFolderInTemp(const UString &path)
{
UString tempPath;
if (!NFile::NDirectory::MyGetTempPath(tempPath))
return false;
if (tempPath.IsEmpty())
return false;
return (tempPath.CompareNoCase(path.Left(tempPath.Length())) == 0);
}
static bool AreThereNamesFromTemp(const UStringVector &fileNames)
{
UString tempPath;
if (!NFile::NDirectory::MyGetTempPath(tempPath))
return false;
if (tempPath.IsEmpty())
return false;
for (int i = 0; i < fileNames.Size(); i++)
if (tempPath.CompareNoCase(fileNames[i].Left(tempPath.Length())) == 0)
return true;
return false;
}
void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &folderPath)
{
if (fileNames.Size() == 0)
return;
const UString archiveName = CreateArchiveName(fileNames.Front(),
(fileNames.Size() > 1), false);
bool createNewArchive = true;
if (!IsFSFolder())
createNewArchive = !DoesItSupportOperations();
if (createNewArchive)
{
UString folderPath2 = folderPath;
if (folderPath2.IsEmpty())
{
NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), folderPath2);
if (IsFolderInTemp(folderPath2))
folderPath2 = L"C:\\"; // fix it
}
CompressFiles(folderPath2, archiveName, fileNames,
false, // email
true, // showDialog
AreThereNamesFromTemp(fileNames) // waitFinish
);
}
else
CopyFrom(fileNames);
}

208
7zip/FileManager/PanelExtract.cpp Executable file
View File

@@ -0,0 +1,208 @@
// PanelExtract.cpp
#include "StdAfx.h"
#include "Windows/COM.h"
#include "Panel.h"
#include "resource.h"
#include "LangUtils.h"
#include "ExtractCallback.h"
#include "Windows/Thread.h"
////////////////////////////////////////////////////////////////
#include "..\UI\Resource\Extract\resource.h"
#include "UpdateCallback100.h"
using namespace NWindows;
struct CThreadExtractInArchive2
{
CMyComPtr<IFolderOperations> FolderOperations;
CRecordVector<UInt32> Indices;
UString DestPath;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
HRESULT Result;
bool MoveMode;
CThreadExtractInArchive2(): MoveMode(false) {}
DWORD Extract()
{
// NCOM::CComInitializer comInitializer;
ExtractCallbackSpec->ProgressDialog.WaitCreating();
if (MoveMode)
Result = FolderOperations->MoveTo(&Indices.Front(), Indices.Size(),
DestPath, ExtractCallback);
else
Result = FolderOperations->CopyTo(&Indices.Front(), Indices.Size(),
DestPath, ExtractCallback);
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadExtractInArchive2 *)param)->Extract();
}
};
HRESULT CPanel::CopyTo(const CRecordVector<UInt32> &indices, const UString &folder,
bool moveMode, bool showErrorMessages, UStringVector *messages)
{
CMyComPtr<IFolderOperations> folderOperations;
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
{
UString errorMessage = LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
if (showErrorMessages)
MessageBox(errorMessage);
else if (messages != 0)
messages->Add(errorMessage);
return E_FAIL;
}
CThreadExtractInArchive2 extracter;
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.ExtractCallbackSpec->ParentWindow = GetParent();
extracter.ExtractCallbackSpec->ShowMessages = showErrorMessages;
UString title = moveMode ?
LangLoadStringW(IDS_MOVING, 0x03020206):
LangLoadStringW(IDS_COPYING, 0x03020205);
UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent();
extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
extracter.ExtractCallbackSpec->Init();
extracter.Indices = indices;
extracter.DestPath = folder;
extracter.FolderOperations = folderOperations;
extracter.MoveMode = moveMode;
CThread extractThread;
if (!extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter))
throw 271824;
extracter.ExtractCallbackSpec->StartProgressDialog(title);
if (messages != 0)
*messages = extracter.ExtractCallbackSpec->Messages;
return extracter.Result;
}
struct CThreadUpdate
{
CMyComPtr<IFolderOperations> FolderOperations;
UString FolderPrefix;
UStringVector FileNames;
CRecordVector<const wchar_t *> FileNamePointers;
CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
CUpdateCallback100Imp *UpdateCallbackSpec;
HRESULT Result;
DWORD Process()
{
NCOM::CComInitializer comInitializer;
UpdateCallbackSpec->ProgressDialog.WaitCreating();
Result = FolderOperations->CopyFrom(
FolderPrefix,
&FileNamePointers.Front(),
FileNamePointers.Size(),
UpdateCallback);
UpdateCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadUpdate *)param)->Process();
}
};
HRESULT CPanel::CopyFrom(const UString &folderPrefix, const UStringVector &filePaths,
bool showErrorMessages, UStringVector *messages)
{
CMyComPtr<IFolderOperations> folderOperations;
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
{
UString errorMessage = LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
if (showErrorMessages)
MessageBox(errorMessage);
else if (messages != 0)
messages->Add(errorMessage);
return E_FAIL;
}
CThreadUpdate updater;
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
updater.UpdateCallback = updater.UpdateCallbackSpec;
UString title = LangLoadStringW(IDS_COPYING, 0x03020205);
UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
updater.UpdateCallbackSpec->ProgressDialog.MainWindow = GetParent();
updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" ");
updater.UpdateCallbackSpec->Init((HWND)*this, false, L"");
updater.FolderOperations = folderOperations;
updater.FolderPrefix = folderPrefix;
updater.FileNames.Reserve(filePaths.Size());
int i;
for(i = 0; i < filePaths.Size(); i++)
updater.FileNames.Add(filePaths[i]);
updater.FileNamePointers.Reserve(updater.FileNames.Size());
for(i = 0; i < updater.FileNames.Size(); i++)
updater.FileNamePointers.Add(updater.FileNames[i]);
CThread thread;
if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater))
throw 271824;
updater.UpdateCallbackSpec->StartProgressDialog(title);
if (messages != 0)
*messages = updater.UpdateCallbackSpec->Messages;
return updater.Result;
}
void CPanel::CopyFrom(const UStringVector &filePaths)
{
UString message = L"Are you sure you want to copy files to archive\n\'";
message += _currentFolderPrefix;
message += L"\' ?";
int res = ::MessageBoxW(*(this), message, L"Confirm File Copy",
MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL);
if (res != IDYES)
return;
CDisableTimerProcessing disableTimerProcessing(*this);
CSelectedState srcSelState;
SaveSelectedState(srcSelState);
HRESULT result = CopyFrom(L"", filePaths, true, 0);
if (result != S_OK)
{
disableTimerProcessing.Restore();
// For Password:
SetFocusToList();
if (result != E_ABORT)
MessageBoxError(result, L"Error");
return;
}
RefreshListCtrl(srcSelState);
disableTimerProcessing.Restore();
SetFocusToList();
}

View File

@@ -31,20 +31,20 @@ HRESULT CPanel::BindToPath(const UString &fullPath)
{ {
CDisableTimerProcessing disableTimerProcessing1(*this); CDisableTimerProcessing disableTimerProcessing1(*this);
CloseOpenFolders(); CloseOpenFolders();
CSysString sysPath = GetSystemString(fullPath); UString sysPath = fullPath;
CFileInfo fileInfo; CFileInfoW fileInfo;
UStringVector reducedParts; UStringVector reducedParts;
while(!sysPath.IsEmpty()) while(!sysPath.IsEmpty())
{ {
if (FindFile(sysPath, fileInfo)) if (FindFile(sysPath, fileInfo))
break; break;
int pos = sysPath.ReverseFind('\\'); int pos = sysPath.ReverseFind(L'\\');
if (pos < 0) if (pos < 0)
sysPath.Empty(); sysPath.Empty();
else else
{ {
if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1) if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1)
reducedParts.Add(GetUnicodeString(sysPath.Mid(pos + 1))); reducedParts.Add(sysPath.Mid(pos + 1));
sysPath = sysPath.Left(pos); sysPath = sysPath.Left(pos);
} }
} }
@@ -58,24 +58,23 @@ HRESULT CPanel::BindToPath(const UString &fullPath)
else if (fileInfo.IsDirectory()) else if (fileInfo.IsDirectory())
{ {
NName::NormalizeDirPathPrefix(sysPath); NName::NormalizeDirPathPrefix(sysPath);
if (_folder->BindToFolder(GetUnicodeString(sysPath), &newFolder) == S_OK) if (_folder->BindToFolder(sysPath, &newFolder) == S_OK)
_folder = newFolder; _folder = newFolder;
} }
else else
{ {
CSysString dirPrefix; UString dirPrefix;
if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix)) if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix))
dirPrefix.Empty(); dirPrefix.Empty();
if (_folder->BindToFolder(GetUnicodeString(dirPrefix), &newFolder) == S_OK) if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK)
{ {
_folder = newFolder; _folder = newFolder;
LoadFullPath(); LoadFullPath();
CSysString fileName; UString fileName;
if (NDirectory::GetOnlyName(sysPath, fileName)) if (NDirectory::GetOnlyName(sysPath, fileName))
{ {
if (OpenItemAsArchive(GetUnicodeString(fileName), if (OpenItemAsArchive(fileName, _currentFolderPrefix,
GetSystemString(_currentFolderPrefix), _currentFolderPrefix + fileName) == S_OK)
GetSystemString(_currentFolderPrefix) + fileName) == S_OK)
{ {
for (int i = reducedParts.Size() - 1; i >= 0; i--) for (int i = reducedParts.Size() - 1; i >= 0; i--)
{ {

View File

@@ -32,7 +32,7 @@ extern HWND g_HWND;
static inline UINT GetCurrentFileCodePage() static inline UINT GetCurrentFileCodePage()
{ return AreFileApisANSI() ? CP_ACP : CP_OEMCP;} { return AreFileApisANSI() ? CP_ACP : CP_OEMCP;}
static LPCTSTR kTempDirPrefix = TEXT("7zO"); static wchar_t *kTempDirPrefix = L"7zO";
static const wchar_t *virusMessage = L"File looks like virus (file name has long spaces in name). 7-Zip will not open it"; static const wchar_t *virusMessage = L"File looks like virus (file name has long spaces in name). 7-Zip will not open it";
@@ -63,8 +63,7 @@ public:
}; };
HRESULT CPanel::OpenItemAsArchive(const UString &name, HRESULT CPanel::OpenItemAsArchive(const UString &name,
const CSysString &folderPath, const UString &folderPath, const UString &filePath)
const CSysString &filePath)
{ {
CFolderLink folderLink; CFolderLink folderLink;
if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo)) if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo))
@@ -99,8 +98,7 @@ HRESULT CPanel::OpenItemAsArchive(const UString &name,
HRESULT CPanel::OpenItemAsArchive(const UString &name) HRESULT CPanel::OpenItemAsArchive(const UString &name)
{ {
return OpenItemAsArchive(name, GetSystemString(_currentFolderPrefix), return OpenItemAsArchive(name, _currentFolderPrefix, _currentFolderPrefix + name);
GetSystemString(_currentFolderPrefix + name));
} }
HRESULT CPanel::OpenItemAsArchive(int index) HRESULT CPanel::OpenItemAsArchive(int index)
@@ -117,7 +115,7 @@ HRESULT CPanel::OpenParentArchiveFolder()
if (_parentFolders.Size() < 2) if (_parentFolders.Size() < 2)
return S_OK; return S_OK;
CFolderLink &folderLink = _parentFolders.Back(); CFolderLink &folderLink = _parentFolders.Back();
NFind::CFileInfo newFileInfo; NFind::CFileInfoW newFileInfo;
if (NFind::FindFile(folderLink.FilePath, newFileInfo)) if (NFind::FindFile(folderLink.FilePath, newFileInfo))
{ {
if (newFileInfo.Size != folderLink.FileInfo.Size || if (newFileInfo.Size != folderLink.FileInfo.Size ||
@@ -150,7 +148,7 @@ static bool DoItemAlwaysStart(const UString &name)
return (ext == UString(L"exe") || ext == UString(L"bat") || ext == UString(L"com")); return (ext == UString(L"exe") || ext == UString(L"bat") || ext == UString(L"com"));
} }
static HANDLE StartEditApplication(CSysString &path, HWND window) static HANDLE StartEditApplication(const UString &path, HWND window)
{ {
CSysString command; CSysString command;
ReadRegEditor(command); ReadRegEditor(command);
@@ -163,7 +161,7 @@ static HANDLE StartEditApplication(CSysString &path, HWND window)
} }
command = CSysString(TEXT("\"")) + command + CSysString(TEXT("\"")); command = CSysString(TEXT("\"")) + command + CSysString(TEXT("\""));
command += TEXT(" \""); command += TEXT(" \"");
command += path; command += GetSystemString(path);
command += TEXT("\""); command += TEXT("\"");
STARTUPINFO startupInfo; STARTUPINFO startupInfo;
@@ -188,14 +186,15 @@ static HANDLE StartEditApplication(CSysString &path, HWND window)
return 0; return 0;
} }
static HANDLE StartApplication(CSysString &path, HWND window) static HANDLE StartApplication(const UString &path, HWND window)
{ {
SHELLEXECUTEINFO execInfo; SHELLEXECUTEINFO execInfo;
execInfo.cbSize = sizeof(execInfo); execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
execInfo.hwnd = NULL; execInfo.hwnd = NULL;
execInfo.lpVerb = NULL; execInfo.lpVerb = NULL;
execInfo.lpFile = path; const CSysString sysPath = GetSystemString(path);
execInfo.lpFile = sysPath;
execInfo.lpParameters = NULL; execInfo.lpParameters = NULL;
execInfo.lpDirectory = NULL; execInfo.lpDirectory = NULL;
execInfo.nShow = SW_SHOWNORMAL; execInfo.nShow = SW_SHOWNORMAL;
@@ -223,18 +222,14 @@ void CPanel::EditItem(int index)
OpenItemInArchive(index, false, true, true); OpenItemInArchive(index, false, true, true);
return; return;
} }
CSysString fullPath = GetSystemString((_currentFolderPrefix + HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemName(index), (HWND)*this);
GetItemName(index)), GetCurrentFileCodePage());
HANDLE hProcess = StartEditApplication(fullPath, (HWND)*this);
if (hProcess != 0) if (hProcess != 0)
::CloseHandle(hProcess); ::CloseHandle(hProcess);
} }
void CPanel::OpenFolderExternal(int index) void CPanel::OpenFolderExternal(int index)
{ {
CSysString fullPath = GetSystemString((_currentFolderPrefix + HANDLE hProcess = StartApplication(_currentFolderPrefix + GetItemName(index), (HWND)*this);
GetItemName(index)), GetCurrentFileCodePage());
HANDLE hProcess = StartApplication(fullPath, (HWND)*this);
if (hProcess != 0) if (hProcess != 0)
::CloseHandle(hProcess); ::CloseHandle(hProcess);
} }
@@ -253,22 +248,21 @@ void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal)
MessageBoxMyError(virusMessage); MessageBoxMyError(virusMessage);
return; return;
} }
CSysString fullPath = GetSystemString((_currentFolderPrefix + name), UString fullPath = _currentFolderPrefix + name;
GetCurrentFileCodePage());
if (tryInternal) if (tryInternal)
if (!tryExternal || !DoItemAlwaysStart(GetItemName(index))) if (!tryExternal || !DoItemAlwaysStart(name))
if (OpenItemAsArchive(index) == S_OK) if (OpenItemAsArchive(index) == S_OK)
return; return;
if (tryExternal) if (tryExternal)
{ {
::SetCurrentDirectory(GetSystemString(_currentFolderPrefix)); NDirectory::MySetCurrentDirectory(_currentFolderPrefix);
HANDLE hProcess = StartApplication(fullPath, (HWND)*this); HANDLE hProcess = StartApplication(fullPath, (HWND)*this);
if (hProcess != 0) if (hProcess != 0)
::CloseHandle(hProcess); ::CloseHandle(hProcess);
} }
} }
HRESULT CPanel::OnOpenItemChanged(const CSysString &folderPath, const UString &itemName) HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &itemName)
{ {
CMyComPtr<IFolderOperations> folderOperations; CMyComPtr<IFolderOperations> folderOperations;
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
@@ -281,14 +275,9 @@ HRESULT CPanel::OnOpenItemChanged(const CSysString &folderPath, const UString &i
fileNames.Add(itemName); fileNames.Add(itemName);
fileNamePointers.Add(fileNames[0]); fileNamePointers.Add(fileNames[0]);
// SetCurrentDirectory(tmpProcessInfo.FolderPath); UString pathPrefix = folderPath;
CSysString pathPrefix = folderPath;
NName::NormalizeDirPathPrefix(pathPrefix); NName::NormalizeDirPathPrefix(pathPrefix);
return folderOperations->CopyFrom( return folderOperations->CopyFrom(pathPrefix, &fileNamePointers.Front(),fileNamePointers.Size(), NULL);
GetUnicodeString(pathPrefix),
&fileNamePointers.Front(),
fileNamePointers.Size(),
NULL);
} }
LRESULT CPanel::OnOpenItemChanged(LPARAM lParam) LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
@@ -337,7 +326,7 @@ static DWORD WINAPI MyThreadFunction(void *param)
if (waitResult != WAIT_OBJECT_0 + 1) if (waitResult != WAIT_OBJECT_0 + 1)
return 1; return 1;
Sleep(200); Sleep(200);
NFind::CFileInfo newFileInfo; NFind::CFileInfoW newFileInfo;
if (NFind::FindFile(tmpProcessInfo->FilePath, newFileInfo)) if (NFind::FindFile(tmpProcessInfo->FilePath, newFileInfo))
{ {
if (newFileInfo.Size != tmpProcessInfo->FileInfo.Size || if (newFileInfo.Size != tmpProcessInfo->FileInfo.Size ||
@@ -361,35 +350,6 @@ static DWORD WINAPI MyThreadFunction(void *param)
return 0; return 0;
} }
static CCriticalSection g_CriticalSection;
struct CThreadExtractInArchive
{
CMyComPtr<IFolderOperations> FolderOperations;
CRecordVector<UINT32> Indices;
UString DestPath;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
HRESULT Result;
DWORD Extract()
{
NCOM::CComInitializer comInitializer;
ExtractCallbackSpec->ProgressDialog.WaitCreating();
Result = FolderOperations->CopyTo(
&Indices.Front(), Indices.Size(),
DestPath, ExtractCallback);
// ExtractCallbackSpec->DestroyWindows();
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadExtractInArchive *)param)->Extract();
}
};
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
bool editMode) bool editMode)
{ {
@@ -400,7 +360,6 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
return; return;
} }
CMyComPtr<IFolderOperations> folderOperations; CMyComPtr<IFolderOperations> folderOperations;
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
{ {
@@ -408,56 +367,35 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
return; return;
} }
CSysString tempDir; NFile::NDirectory::CTempDirectoryW tempDirectory;
if (!CreateTempDirectory(kTempDirPrefix, tempDir)) tempDirectory.Create(kTempDirPrefix);
return; UString tempDir = tempDirectory.GetPath();
UString tempDirNorm = tempDir;
NFile::NName::NormalizeDirPathPrefix(tempDirNorm);
CThreadExtractInArchive extracter; CRecordVector<UInt32> indices;
indices.Add(index);
extracter.ExtractCallbackSpec = new CExtractCallbackImp; HRESULT result = CopyTo(indices, tempDirNorm, false, true, 0);
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.ExtractCallbackSpec->ParentWindow = GetParent();
// extracter.ExtractCallbackSpec->_appTitle.Window = extracter.ExtractCallbackSpec->_parentWindow;
// extracter.ExtractCallbackSpec->_appTitle.Title = progressWindowTitle;
// extracter.ExtractCallbackSpec->_appTitle.AddTitle = title + CSysString(TEXT(" "));
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; if ((result != S_OK && result != E_ABORT))
extracter.ExtractCallbackSpec->Init();
extracter.Indices.Add(index);
extracter.DestPath = GetUnicodeString(tempDir + NFile::NName::kDirDelimiter);
extracter.FolderOperations = folderOperations;
CThread extractThread;
if (!extractThread.Create(CThreadExtractInArchive::MyThreadFunction, &extracter))
throw 271824;
extracter.ExtractCallbackSpec->StartProgressDialog(LangLoadStringW(IDS_OPENNING, 0x03020283));
if (extracter.Result != S_OK || extracter.ExtractCallbackSpec->Messages.Size() != 0)
{ {
if (extracter.Result != S_OK) MessageBoxError(result, L"7-Zip");
if (extracter.Result != E_ABORT)
{
// MessageBox(L"Can not extract item");
// NError::MyFormatMessage(systemError.ErrorCode, message);
MessageBoxError(extracter.Result, L"7-Zip");
}
return; return;
} }
CSysString tempFileName = tempDir + NFile::NName::kDirDelimiter + UString tempFilePath = tempDirNorm + name;
GetSystemString(name);
std::auto_ptr<CTmpProcessInfo> tmpProcessInfo(new CTmpProcessInfo()); std::auto_ptr<CTmpProcessInfo> tmpProcessInfo(new CTmpProcessInfo());
tmpProcessInfo->FolderPath = tempDir; tmpProcessInfo->FolderPath = tempDir;
tmpProcessInfo->FilePath = tempFileName; tmpProcessInfo->FilePath = tempFilePath;
if (!NFind::FindFile(tempFileName, tmpProcessInfo->FileInfo)) if (!NFind::FindFile(tempFilePath, tmpProcessInfo->FileInfo))
return; return;
if (tryInternal) if (tryInternal)
{ {
if (!tryExternal || !DoItemAlwaysStart(name)) if (!tryExternal || !DoItemAlwaysStart(name))
if (OpenItemAsArchive(name, tempDir, tempFileName) == S_OK) if (OpenItemAsArchive(name, tempDir, tempFilePath) == S_OK)
{ {
RefreshListCtrl(); RefreshListCtrl();
return; return;
@@ -471,9 +409,9 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
HANDLE hProcess; HANDLE hProcess;
if (editMode) if (editMode)
hProcess = StartEditApplication(tempFileName, (HWND)*this); hProcess = StartEditApplication(tempFilePath, (HWND)*this);
else else
hProcess = StartApplication(tempFileName, (HWND)*this); hProcess = StartApplication(tempFilePath, (HWND)*this);
if (hProcess == 0) if (hProcess == 0)
return; return;
@@ -482,10 +420,11 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix; tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix;
tmpProcessInfo->ItemName = name; tmpProcessInfo->ItemName = name;
tmpProcessInfo->ProcessHandle = hProcess; tmpProcessInfo->ProcessHandle = hProcess;
CThread thread; CThread thread;
if (!thread.Create(MyThreadFunction, tmpProcessInfo.get())) if (!thread.Create(MyThreadFunction, tmpProcessInfo.get()))
throw 271824; throw 271824;
tempDirectory.DisableDeleting();
tmpProcessInfo.release(); tmpProcessInfo.release();
tmpProcessInfoRelease._needDelete = false; tmpProcessInfoRelease._needDelete = false;
} }

View File

@@ -297,7 +297,7 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
_listView.DeleteAllItems(); _listView.DeleteAllItems();
_selectedStatusVector.Clear(); _selectedStatusVector.Clear();
_realIndices.Clear(); // _realIndices.Clear();
_startGroupSelect = 0; _startGroupSelect = 0;
_selectionIsDefined = false; _selectionIsDefined = false;
@@ -511,6 +511,27 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UINT32> &indices) const
} }
} }
/*
void CPanel::GetOperatedListViewIndices(CRecordVector<UInt32> &indices) const
{
indices.Clear();
int numItems = _listView.GetItemCount();
for (int i = 0; i < numItems; i++)
{
int realIndex = GetRealItemIndex(i);
if (realIndex >= 0)
if (_selectedStatusVector[realIndex])
indices.Add(i);
}
if (indices.IsEmpty())
{
int focusedItem = _listView.GetFocusedItem();
if (focusedItem >= 0)
indices.Add(focusedItem);
}
}
*/
void CPanel::EditItem() void CPanel::EditItem()
{ {
int focusedItem = _listView.GetFocusedItem(); int focusedItem = _listView.GetFocusedItem();

View File

@@ -125,7 +125,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result)
{ {
if (!alt && !ctrl) if (!alt && !ctrl)
{ {
_panelCallback->OnCopy(UStringVector(), false, shift); _panelCallback->OnCopy(false, shift);
return true; return true;
} }
break; break;
@@ -134,7 +134,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result)
{ {
if (!alt && !ctrl) if (!alt && !ctrl)
{ {
_panelCallback->OnCopy(UStringVector(), true, shift); _panelCallback->OnCopy(true, shift);
return true; return true;
} }
break; break;

View File

@@ -230,12 +230,6 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
// TODO : Handler default action... // TODO : Handler default action...
return 0; return 0;
case LVN_BEGINDRAG:
case LVN_BEGINRDRAG:
{
SendRefreshStatusBarMessage();
return 0;
}
case LVN_ITEMCHANGED: case LVN_ITEMCHANGED:
{ {
NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh; NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh;
@@ -268,7 +262,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
case LVN_BEGINDRAG: case LVN_BEGINDRAG:
case LVN_BEGINRDRAG: case LVN_BEGINRDRAG:
{ {
// OnDrag((LPNMLISTVIEW)header); OnDrag((LPNMLISTVIEW)header);
RefreshStatusBar(); RefreshStatusBar();
break; break;
} }

View File

@@ -83,7 +83,7 @@ BEGIN
PUSHBUTTON "Support",IDC_ABOUT_BUTTON_EMAIL,136,30,94,14 PUSHBUTTON "Support",IDC_ABOUT_BUTTON_EMAIL,136,30,94,14
PUSHBUTTON "Register",IDC_ABOUT_BUTTON_REGISTER,136,53,94,14 PUSHBUTTON "Register",IDC_ABOUT_BUTTON_REGISTER,136,53,94,14
ICON IDI_LOGO,IDC_STATIC,7,7,20,20,SS_REALSIZEIMAGE ICON IDI_LOGO,IDC_STATIC,7,7,20,20,SS_REALSIZEIMAGE
LTEXT "7-Zip 4.20",IDC_STATIC,7,54,119,9 LTEXT "7-Zip 4.23",IDC_STATIC,7,54,119,9
LTEXT "Copyright (c) 1999-2005 Igor Pavlov",IDC_STATIC,7,67, LTEXT "Copyright (c) 1999-2005 Igor Pavlov",IDC_STATIC,7,67,
119,17 119,17
LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.", LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.",

View File

@@ -3,6 +3,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "CopyDialog.h" #include "CopyDialog.h"
#include "Common/StringConvert.h"
#include "Windows/Control/Static.h" #include "Windows/Control/Static.h"
#include "Windows/Shell.h" #include "Windows/Shell.h"
#include "Windows/FileName.h" #include "Windows/FileName.h"
@@ -33,7 +35,7 @@ bool CCopyDialog::OnInit()
staticContol.Attach(GetItem(IDC_COPY_STATIC)); staticContol.Attach(GetItem(IDC_COPY_STATIC));
staticContol.SetText(Static); staticContol.SetText(Static);
for(int i = 0; i < Strings.Size(); i++) for(int i = 0; i < Strings.Size(); i++)
_path.AddString(Strings[i]); _path.AddString(GetSystemString(Strings[i]));
_path.SetText(Value); _path.SetText(Value);
return CModalDialog::OnInit(); return CModalDialog::OnInit();
} }

View File

@@ -18,7 +18,7 @@ public:
UString Title; UString Title;
UString Static; UString Static;
UString Value; UString Value;
CSysStringVector Strings; UStringVector Strings;
INT_PTR Create(HWND parentWindow = 0) INT_PTR Create(HWND parentWindow = 0)
{ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COPY), parentWindow); } { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COPY), parentWindow); }

View File

@@ -2,6 +2,7 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "MessagesDialog.h" #include "MessagesDialog.h"
#include "Common/StringConvert.h"
#include "Windows/ResourceString.h" #include "Windows/ResourceString.h"
#ifdef LANG #ifdef LANG
@@ -39,18 +40,18 @@ void CMessagesDialog::AddMessageDirect(LPCTSTR message)
_messageList.SetItem(&item); _messageList.SetItem(&item);
} }
void CMessagesDialog::AddMessage(LPCTSTR message) void CMessagesDialog::AddMessage(LPCWSTR message)
{ {
CSysString s = message; UString s = message;
while (!s.IsEmpty()) while (!s.IsEmpty())
{ {
int pos = s.Find(TEXT('\n')); int pos = s.Find(L'\n');
if (pos < 0) if (pos < 0)
break; break;
AddMessageDirect(s.Left(pos)); AddMessageDirect(GetSystemString(s.Left(pos)));
s.Delete(0, pos + 1); s.Delete(0, pos + 1);
} }
AddMessageDirect(s); AddMessageDirect(GetSystemString(s));
} }
bool CMessagesDialog::OnInit() bool CMessagesDialog::OnInit()

View File

@@ -12,10 +12,10 @@ class CMessagesDialog: public NWindows::NControl::CModalDialog
{ {
NWindows::NControl::CListView _messageList; NWindows::NControl::CListView _messageList;
void AddMessageDirect(LPCTSTR message); void AddMessageDirect(LPCTSTR message);
void AddMessage(LPCTSTR message); void AddMessage(LPCWSTR message);
virtual bool OnInit(); virtual bool OnInit();
public: public:
const CSysStringVector *Messages; const UStringVector *Messages;
INT_PTR Create(HWND parentWindow = 0) INT_PTR Create(HWND parentWindow = 0)
{ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_MESSAGES), parentWindow); } { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_MESSAGES), parentWindow); }
}; };

View File

@@ -15,7 +15,7 @@ using namespace NWindows;
CUpdateCallback100Imp::~CUpdateCallback100Imp() CUpdateCallback100Imp::~CUpdateCallback100Imp()
{ {
if (!Messages.IsEmpty()) if (ShowMessages && !Messages.IsEmpty())
{ {
CMessagesDialog messagesDialog; CMessagesDialog messagesDialog;
messagesDialog.Messages = &Messages; messagesDialog.Messages = &Messages;
@@ -25,7 +25,7 @@ CUpdateCallback100Imp::~CUpdateCallback100Imp()
void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message) void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message)
{ {
Messages.Add(GetSystemString(message)); Messages.Add(message);
} }
STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size) STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size)

View File

@@ -41,18 +41,21 @@ private:
UString _password; UString _password;
void AddErrorMessage(LPCWSTR message); void AddErrorMessage(LPCWSTR message);
CSysStringVector Messages; bool ShowMessages;
public: public:
CUpdateCallback100Imp(): ShowMessages(true) {}
~CUpdateCallback100Imp(); ~CUpdateCallback100Imp();
CProgressDialog ProgressDialog; CProgressDialog ProgressDialog;
HWND _parentWindow; HWND _parentWindow;
UStringVector Messages;
void Init(HWND parentWindow, void Init(HWND parentWindow,
bool passwordIsDefined, const UString &password) bool passwordIsDefined, const UString &password)
{ {
_passwordIsDefined = passwordIsDefined; _passwordIsDefined = passwordIsDefined;
_password = password; _password = password;
_parentWindow = parentWindow; _parentWindow = parentWindow;
} }
void StartProgressDialog(const UString &title) void StartProgressDialog(const UString &title)
{ {

View File

@@ -82,8 +82,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -101,14 +101,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip File Manager\0" VALUE "FileDescription", "7-Zip File Manager\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7zFM\0" VALUE "InternalName", "7zFM\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7zFM.exe\0" VALUE "OriginalFilename", "7zFM.exe\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -161,7 +161,8 @@ STDMETHODIMP CAgent::DoOperation(
UString folderPrefix = _folderPrefix; UString folderPrefix = _folderPrefix;
NFile::NName::NormalizeDirPathPrefix(folderPrefix); NFile::NName::NormalizeDirPathPrefix(folderPrefix);
RINOK(::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems)); UString errorPath;
RINOK(::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems, errorPath));
NWindows::NDLL::CLibrary library; NWindows::NDLL::CLibrary library;

View File

@@ -719,7 +719,9 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed); AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
CObjectVector<CDirItem> dirItems; CObjectVector<CDirItem> dirItems;
EnumerateItems(archiveWildcardCensor, dirItems, NULL); UString errorPath;
if (EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPath) != S_OK)
throw "cannot find archive";
UStringVector archivePaths; UStringVector archivePaths;
int i; int i;
for (i = 0; i < dirItems.Size(); i++) for (i = 0; i < dirItems.Size(); i++)

View File

@@ -35,7 +35,7 @@ static bool IsItWindowsNT()
} }
HRESULT MyCreateProcess(const UString &params, HRESULT MyCreateProcess(const UString &params,
LPCTSTR curDir, LPCTSTR curDir, bool waitFinish,
NWindows::NSynchronization::CEvent *event) NWindows::NSynchronization::CEvent *event)
{ {
STARTUPINFO startupInfo; STARTUPINFO startupInfo;
@@ -57,13 +57,15 @@ HRESULT MyCreateProcess(const UString &params,
return ::GetLastError(); return ::GetLastError();
else else
{ {
if (event != NULL) ::CloseHandle(processInformation.hThread);
if (waitFinish)
WaitForSingleObject(processInformation.hProcess, INFINITE);
else if (event != NULL)
{ {
HANDLE handles[] = {processInformation.hProcess, *event }; HANDLE handles[] = {processInformation.hProcess, *event };
::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]),
handles, FALSE, INFINITE); handles, FALSE, INFINITE);
} }
::CloseHandle(processInformation.hThread);
::CloseHandle(processInformation.hProcess); ::CloseHandle(processInformation.hProcess);
} }
return S_OK; return S_OK;
@@ -175,7 +177,8 @@ HRESULT CompressFiles(
const UStringVector &names, const UStringVector &names,
// const UString &outFolder, // const UString &outFolder,
bool email, bool email,
bool showDialog) bool showDialog,
bool waitFinish)
{ {
/* /*
UString curDir; UString curDir;
@@ -281,7 +284,7 @@ HRESULT CompressFiles(
CSysString sysCurDir = GetSystemString(curDir); CSysString sysCurDir = GetSystemString(curDir);
RINOK(MyCreateProcess(params, RINOK(MyCreateProcess(params,
(sysCurDir.IsEmpty()? 0: (LPCTSTR)sysCurDir), (sysCurDir.IsEmpty()? 0: (LPCTSTR)sysCurDir),
&event)); waitFinish, &event));
} }
catch(...) catch(...)
{ {
@@ -310,7 +313,7 @@ static HRESULT ExtractGroupCommand(const UStringVector &archivePaths,
CFileMapping fileMapping; CFileMapping fileMapping;
NSynchronization::CEvent event; NSynchronization::CEvent event;
RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2)); RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2));
return MyCreateProcess(params2, 0, &event); return MyCreateProcess(params2, 0, false, &event);
} }
HRESULT ExtractArchives(const UStringVector &archivePaths, HRESULT ExtractArchives(const UStringVector &archivePaths,

View File

@@ -7,14 +7,14 @@
#include "Windows/Synchronization.h" #include "Windows/Synchronization.h"
HRESULT MyCreateProcess(const UString &params, HRESULT MyCreateProcess(const UString &params,
LPCTSTR lpCurrentDirectory, LPCTSTR lpCurrentDirectory, bool waitFinish,
NWindows::NSynchronization::CEvent *event = NULL); NWindows::NSynchronization::CEvent *event);
HRESULT CompressFiles( HRESULT CompressFiles(
const UString &curDir, const UString &curDir,
const UString &archiveName, const UString &archiveName,
const UStringVector &names, const UStringVector &names,
// const UString &outFolder, // const UString &outFolder,
bool email, bool showDialog); bool email, bool showDialog, bool waitFinish);
HRESULT ExtractArchives( HRESULT ExtractArchives(
const UStringVector &archivePaths, const UStringVector &archivePaths,

View File

@@ -35,7 +35,8 @@ static HRESULT EnumerateDirectory(
const UString &baseFolderPrefix, const UString &baseFolderPrefix,
const UString &directory, const UString &directory,
const UString &prefix, const UString &prefix,
CObjectVector<CDirItem> &dirItems) CObjectVector<CDirItem> &dirItems,
UString &errorPath)
{ {
NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard)); NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));
while (true) while (true)
@@ -43,7 +44,11 @@ static HRESULT EnumerateDirectory(
NFind::CFileInfoW fileInfo; NFind::CFileInfoW fileInfo;
bool found; bool found;
if (!enumerator.Next(fileInfo, found)) if (!enumerator.Next(fileInfo, found))
return ::GetLastError(); {
HRESULT error = ::GetLastError();
errorPath = baseFolderPrefix + directory;
return error;
}
if (!found) if (!found)
break; break;
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
@@ -51,7 +56,7 @@ static HRESULT EnumerateDirectory(
if (fileInfo.IsDirectory()) if (fileInfo.IsDirectory())
{ {
RINOK(EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), RINOK(EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems)); prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPath));
} }
} }
return S_OK; return S_OK;
@@ -61,7 +66,8 @@ HRESULT EnumerateDirItems(
const UString &baseFolderPrefix, const UString &baseFolderPrefix,
const UStringVector &fileNames, const UStringVector &fileNames,
const UString &archiveNamePrefix, const UString &archiveNamePrefix,
CObjectVector<CDirItem> &dirItems) CObjectVector<CDirItem> &dirItems,
UString &errorPath)
{ {
for(int i = 0; i < fileNames.Size(); i++) for(int i = 0; i < fileNames.Size(); i++)
{ {
@@ -74,7 +80,7 @@ HRESULT EnumerateDirItems(
{ {
RINOK(EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), RINOK(EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),
archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter), archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
dirItems)); dirItems, errorPath));
} }
} }
return S_OK; return S_OK;
@@ -87,7 +93,8 @@ static HRESULT EnumerateDirItems(
const UString &addArchivePrefix, const UString &addArchivePrefix,
CObjectVector<CDirItem> &dirItems, CObjectVector<CDirItem> &dirItems,
bool enterToSubFolders, bool enterToSubFolders,
IEnumDirItemCallback *callback) IEnumDirItemCallback *callback,
UString &errorPath)
{ {
if (!enterToSubFolders) if (!enterToSubFolders)
if (curNode.NeedCheckSubDirs()) if (curNode.NeedCheckSubDirs())
@@ -100,7 +107,11 @@ static HRESULT EnumerateDirItems(
NFind::CFileInfoW fileInfo; NFind::CFileInfoW fileInfo;
bool found; bool found;
if (!enumerator.Next(fileInfo, found)) if (!enumerator.Next(fileInfo, found))
return ::GetLastError(); {
HRESULT error = ::GetLastError();
errorPath = diskPrefix;
return error;
}
if (!found) if (!found)
break; break;
@@ -140,20 +151,23 @@ static HRESULT EnumerateDirItems(
RINOK(EnumerateDirItems(*nextNode, RINOK(EnumerateDirItems(*nextNode,
diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter), diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
archivePrefixNew, addArchivePrefixNew, archivePrefixNew, addArchivePrefixNew,
dirItems, enterToSubFolders2, callback)); dirItems, enterToSubFolders2, callback, errorPath));
} }
return S_OK; return S_OK;
} }
HRESULT EnumerateItems(const NWildcard::CCensor &censor, HRESULT EnumerateItems(
CObjectVector<CDirItem> &dirItems, IEnumDirItemCallback *callback) const NWildcard::CCensor &censor,
CObjectVector<CDirItem> &dirItems,
IEnumDirItemCallback *callback,
UString &errorPath)
{ {
for (int i = 0; i < censor.Pairs.Size(); i++) for (int i = 0; i < censor.Pairs.Size(); i++)
{ {
if (callback) if (callback)
RINOK(callback->CheckBreak()); RINOK(callback->CheckBreak());
const NWildcard::CPair &pair = censor.Pairs[i]; const NWildcard::CPair &pair = censor.Pairs[i];
RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", L"", dirItems, false, callback)); RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", L"", dirItems, false, callback, errorPath));
} }
return S_OK; return S_OK;
} }

View File

@@ -19,7 +19,8 @@ HRESULT EnumerateDirItems(
const UString &baseFolderPrefix, const UString &baseFolderPrefix,
const UStringVector &fileNames, const UStringVector &fileNames,
const UString &archiveNamePrefix, const UString &archiveNamePrefix,
CObjectVector<CDirItem> &dirItems); CObjectVector<CDirItem> &dirItems,
UString &errorPath);
struct IEnumDirItemCallback struct IEnumDirItemCallback
{ {
@@ -27,7 +28,10 @@ struct IEnumDirItemCallback
}; };
HRESULT EnumerateItems(const NWildcard::CCensor &censor, HRESULT EnumerateItems(
CObjectVector<CDirItem> &dirItems, IEnumDirItemCallback *callback); const NWildcard::CCensor &censor,
CObjectVector<CDirItem> &dirItems,
IEnumDirItemCallback *callback,
UString &errorPath);
#endif #endif

View File

@@ -694,7 +694,14 @@ HRESULT UpdateArchive(const NWildcard::CCensor &censor,
CEnumDirItemUpdateCallback enumCallback; CEnumDirItemUpdateCallback enumCallback;
enumCallback.Callback = callback; enumCallback.Callback = callback;
RINOK(callback->StartScanning()); RINOK(callback->StartScanning());
RINOK(EnumerateItems(censor, dirItems, &enumCallback)); UString errorPath;
HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPath);
if(res != S_OK)
{
errorInfo.Message = L"Scanning error";
errorInfo.FileName = errorPath;
return res;
}
RINOK(callback->FinishScanning()); RINOK(callback->FinishScanning());
} }
} }

View File

@@ -54,7 +54,7 @@ static const char *kCopyrightString = "\n7-Zip"
" [NT]" " [NT]"
#endif #endif
" 4.20 Copyright (c) 1999-2005 Igor Pavlov 2005-05-30\n"; " 4.23 Copyright (c) 1999-2005 Igor Pavlov 2005-06-29\n";
static const char *kHelpString = static const char *kHelpString =
"\nUsage: 7z" "\nUsage: 7z"

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip Console version\0" VALUE "FileDescription", "7-Zip Console version\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7z\0" VALUE "InternalName", "7z\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7z.exe\0" VALUE "OriginalFilename", "7z.exe\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -267,6 +267,15 @@ static UString GetSubFolderNameForExtract(const UString &archiveName)
return archiveName + UString(L"~"); return archiveName + UString(L"~");
} }
static UString GetReducedString(const UString &s)
{
const int kMaxSize = 64;
if (s.Length() < kMaxSize)
return s;
const int kFirstPartSize = kMaxSize / 2;
return s.Left(kFirstPartSize) + UString(L" ... ") + s.Right(kMaxSize - kFirstPartSize);
}
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags) UINT commandIDFirst, UINT commandIDLast, UINT flags)
{ {
@@ -388,7 +397,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
folder = L'*'; folder = L'*';
folder += L'\\'; folder += L'\\';
commandMapItem.Folder = folderPrefix + folder; commandMapItem.Folder = folderPrefix + folder;
s = MyFormatNew(s, folder); s = MyFormatNew(s, GetReducedString(folder));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
_commandMap.push_back(commandMapItem); _commandMap.push_back(commandMapItem);
} }
@@ -426,7 +435,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
FillCommand2(kCompressTo, s, commandMapItem); FillCommand2(kCompressTo, s, commandMapItem);
commandMapItem.Folder = archivePathPrefix; commandMapItem.Folder = archivePathPrefix;
commandMapItem.Archive = archiveName7z; commandMapItem.Archive = archiveName7z;
UString t = UString(L"\"") + archiveName7z + UString(L"\""); UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\"");
s = MyFormatNew(s, t); s = MyFormatNew(s, t);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
_commandMap.push_back(commandMapItem); _commandMap.push_back(commandMapItem);
@@ -449,7 +458,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UString s; UString s;
FillCommand2(kCompressToEmail, s, commandMapItem); FillCommand2(kCompressToEmail, s, commandMapItem);
commandMapItem.Archive = archiveName7z; commandMapItem.Archive = archiveName7z;
UString t = UString(L"\"") + archiveName7z + UString(L"\""); UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\"");
s = MyFormatNew(s, t); s = MyFormatNew(s, t);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
_commandMap.push_back(commandMapItem); _commandMap.push_back(commandMapItem);
@@ -633,7 +642,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
params += L" \""; params += L" \"";
params += _fileNames[0]; params += _fileNames[0];
params += L"\""; params += L"\"";
MyCreateProcess(params, 0); MyCreateProcess(params, 0, false, 0);
break; break;
} }
case kExtract: case kExtract:
@@ -659,7 +668,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
bool showDialog = (commandInternalID == kCompress) || bool showDialog = (commandInternalID == kCompress) ||
(commandInternalID == kCompressEmail); (commandInternalID == kCompressEmail);
CompressFiles(commandMapItem.Folder, commandMapItem.Archive, CompressFiles(commandMapItem.Folder, commandMapItem.Archive,
_fileNames, email, showDialog); _fileNames, email, showDialog, false);
break; break;
} }
} }

View File

@@ -68,8 +68,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -87,14 +87,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip Shell Extension\0" VALUE "FileDescription", "7-Zip Shell Extension\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7-zip\0" VALUE "InternalName", "7-zip\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7-zip.dll\0" VALUE "OriginalFilename", "7-zip.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip FAR Plugin\0" VALUE "FileDescription", "7-Zip FAR Plugin\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7-ZipFar\0" VALUE "InternalName", "7-ZipFar\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7-ZipFar.dll\0" VALUE "OriginalFilename", "7-ZipFar.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -1,4 +1,4 @@
// UpdateCallbackConsole.cpp // UpdateCallbackGUI.cpp
#include "StdAfx.h" #include "StdAfx.h"
@@ -34,7 +34,7 @@ void CUpdateCallbackGUI::Init()
void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message) void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message)
{ {
Messages.Add(GetSystemString(message)); Messages.Add(message);
} }
HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result) HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result)

View File

@@ -53,7 +53,7 @@ public:
ProgressDialog.Create(title, ParentWindow); ProgressDialog.Create(title, ParentWindow);
} }
CSysStringVector Messages; UStringVector Messages;
int NumArchiveErrors; int NumArchiveErrors;
void AddErrorMessage(LPCWSTR message); void AddErrorMessage(LPCWSTR message);
}; };

View File

@@ -184,13 +184,17 @@ static HRESULT ShowDialog(const NWildcard::CCensor &censor,
CArchiverInfo archiverInfo; CArchiverInfo archiverInfo;
ReadArchiverInfoList(archivers); ReadArchiverInfoList(archivers);
UString currentDirPrefix; UString currentDirPrefix;
{
if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix))
return E_FAIL;
NName::NormalizeDirPathPrefix(currentDirPrefix);
}
bool oneFile = false; bool oneFile = false;
NFind::CFileInfoW fileInfo; NFind::CFileInfoW fileInfo;
if (censor.Pairs.Size() > 0) if (censor.Pairs.Size() > 0)
{ {
const NWildcard::CPair &pair = censor.Pairs[0]; const NWildcard::CPair &pair = censor.Pairs[0];
currentDirPrefix = pair.Prefix;
if (pair.Head.Items.Size() > 0) if (pair.Head.Items.Size() > 0)
{ {
const NWildcard::CItem &item = pair.Head.Items[0]; const NWildcard::CItem &item = pair.Head.Items[0];

View File

@@ -74,8 +74,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,20,0,0 FILEVERSION 4,23,0,0
PRODUCTVERSION 4,20,0,0 PRODUCTVERSION 4,23,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -93,14 +93,14 @@ BEGIN
VALUE "Comments", "\0" VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0" VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip GUI Module\0" VALUE "FileDescription", "7-Zip GUI Module\0"
VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "FileVersion", "4, 23, 0, 0\0"
VALUE "InternalName", "7zg\0" VALUE "InternalName", "7zg\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7zg.exe\0" VALUE "OriginalFilename", "7zg.exe\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0" VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "ProductVersion", "4, 23, 0, 0\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END

View File

@@ -1,7 +1,7 @@
7z ANSI-C Decoder 4.16 7z ANSI-C Decoder 4.22
---------------------- ----------------------
7z ANSI-C Decoder 4.16 Copyright (C) 1999-2005 Igor Pavlov 7z ANSI-C Decoder 4.22 Copyright (C) 1999-2005 Igor Pavlov
7z ANSI-C provides 7z/LZMA decoding. 7z ANSI-C provides 7z/LZMA decoding.
7z ANSI-C version is simplified version ported from C++ code. 7z ANSI-C version is simplified version ported from C++ code.
@@ -14,7 +14,7 @@ compression ratio and very fast decompression.
LICENSE LICENSE
------- -------
Read lzma.txt for informaton about license. Read lzma.txt for information about license.
Files Files
@@ -105,7 +105,7 @@ Memory allocation
7z Decoder uses two memory pools: 7z Decoder uses two memory pools:
1) Temporary pool 1) Temporary pool
2) Main pool 2) Main pool
Such scheme can allow you to avoid fragmentation of alocated blocks. Such scheme can allow you to avoid fragmentation of allocated blocks.
Steps for using 7z decoder Steps for using 7z decoder
-------------------------- --------------------------
@@ -156,7 +156,7 @@ SzArchiveOpen function allocates and frees temporary structures by "allocTemp" f
ISzAlloc *allocMain, ISzAlloc *allocMain,
ISzAlloc *allocTemp); ISzAlloc *allocTemp);
If you need to decompress more than one file, you can send these values from preevious call: If you need to decompress more than one file, you can send these values from previous call:
blockIndex, blockIndex,
outBuffer, outBuffer,
outBufferSize, outBufferSize,
@@ -174,7 +174,7 @@ SzArchiveOpen function allocates and frees temporary structures by "allocTemp" f
Memory requirements for .7z decoding Memory requirements for .7z decoding
------------------------------------ ------------------------------------
Memory usage for Archive openning: Memory usage for Archive opening:
- Temporary pool: - Temporary pool:
- Memory for compressed .7z headers (if _LZMA_IN_CB is not defined) - Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
- Memory for uncompressed .7z headers - Memory for uncompressed .7z headers
@@ -228,7 +228,7 @@ _SZ_NO_INT_64 - define it if your compiler doesn't support long long int
_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs. _LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs.
_SZ_ONE_DIRECTORY - define it if you want to locate all source files to one direcory _SZ_ONE_DIRECTORY - define it if you want to locate all source files to one directory
_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr. _SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.

View File

@@ -1,7 +1,7 @@
7z Format description (2.30 Beta 25) 7z Format description (2.30 Beta 25)
----------------------------------- -----------------------------------
This file contain descrition of 7z archive format. This file contains description of 7z archive format.
7z archive can contain files compressed with any method. 7z archive can contain files compressed with any method.
See "Methods.txt" for description for defined compressing methods. See "Methods.txt" for description for defined compressing methods.

View File

@@ -2,7 +2,7 @@
;Defines ;Defines
!define VERSION_MAJOR 4 !define VERSION_MAJOR 4
!define VERSION_MINOR 20 !define VERSION_MINOR 23
!define VERSION_POSTFIX_FULL "" !define VERSION_POSTFIX_FULL ""
!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}" !define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}"
!define VERSION_POSTFIX "" !define VERSION_POSTFIX ""
@@ -155,6 +155,7 @@ Section
File eo.txt File eo.txt
File es.txt File es.txt
File et.txt File et.txt
File ext.txt
File fa.txt File fa.txt
File fi.txt File fi.txt
File fr.txt File fr.txt
@@ -173,6 +174,7 @@ Section
File lv.txt File lv.txt
File mk.txt File mk.txt
File mn.txt File mn.txt
File ms.txt
File nl.txt File nl.txt
File no.txt File no.txt
File pl.txt File pl.txt
@@ -349,6 +351,7 @@ Section "Uninstall"
Delete $INSTDIR\Lang\eo.txt Delete $INSTDIR\Lang\eo.txt
Delete $INSTDIR\Lang\es.txt Delete $INSTDIR\Lang\es.txt
Delete $INSTDIR\Lang\et.txt Delete $INSTDIR\Lang\et.txt
Delete $INSTDIR\Lang\ext.txt
Delete $INSTDIR\Lang\fa.txt Delete $INSTDIR\Lang\fa.txt
Delete $INSTDIR\Lang\fi.txt Delete $INSTDIR\Lang\fi.txt
Delete $INSTDIR\Lang\fr.txt Delete $INSTDIR\Lang\fr.txt
@@ -367,6 +370,7 @@ Section "Uninstall"
Delete $INSTDIR\Lang\lv.txt Delete $INSTDIR\Lang\lv.txt
Delete $INSTDIR\Lang\mk.txt Delete $INSTDIR\Lang\mk.txt
Delete $INSTDIR\Lang\mn.txt Delete $INSTDIR\Lang\mn.txt
Delete $INSTDIR\Lang\ms.txt
Delete $INSTDIR\Lang\nl.txt Delete $INSTDIR\Lang\nl.txt
Delete $INSTDIR\Lang\no.txt Delete $INSTDIR\Lang\no.txt
Delete $INSTDIR\Lang\pl.txt Delete $INSTDIR\Lang\pl.txt

View File

@@ -1,6 +1,11 @@
Sources history of the 7-Zip Sources history of the 7-Zip
---------------------------- ----------------------------
Version 4.23 2005-06-29
--------------------------------------
- Bug was fixed: memory leak in Cab decoder.
Version 4.19 beta 2005-05-21 Version 4.19 beta 2005-05-21
-------------------------------------- --------------------------------------
- BZip2 code was rewritten. Now 7-Zip doesn't use original BZip2 code. - BZip2 code was rewritten. Now 7-Zip doesn't use original BZip2 code.

View File

@@ -1,7 +1,7 @@
LZMA SDK 4.17 LZMA SDK 4.22
------------- -------------
LZMA SDK 4.17 Copyright (C) 1999-2005 Igor Pavlov LZMA SDK 4.22 Copyright (C) 1999-2005 Igor Pavlov
LZMA SDK provides developers with documentation, source code, LZMA SDK provides developers with documentation, source code,
and sample code necessary to write software that uses LZMA compression. and sample code necessary to write software that uses LZMA compression.
@@ -50,7 +50,8 @@ of LZMA SDK as update for previous versions.
SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits
you to use code of examples (LzmaTest.c) as public domain code. you to use code of examples (LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp) as
public domain code.
GNU LGPL and CPL licenses are pretty similar and both these GNU LGPL and CPL licenses are pretty similar and both these
@@ -142,7 +143,10 @@ SRC
LzmaDecode.h - interface for LZMA decoding on ANSI-C LzmaDecode.h - interface for LZMA decoding on ANSI-C
LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version) LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version)
LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version) LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version)
LzmaTest.c - test application that decodes LZMA encoded file LzmaTest.c - test application that decodes LZMA encoded file
LzmaStateDecode.h - interface for LZMA decoding (State version)
LzmaStateDecode.c - LZMA decoding on ANSI-C (State version)
LzmaStateTest.c - test application (State version)
Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
Archive - files related to archiving Archive - files related to archiving
7z_C - 7z ANSI-C Decoder 7z_C - 7z ANSI-C Decoder
@@ -180,7 +184,7 @@ Some critical operations that affect to speed of LZMA decompression:
2) Misspredicted branches (penalty mostly depends from pipeline length) 2) Misspredicted branches (penalty mostly depends from pipeline length)
3) 32-bit shift and arithmetic operations 3) 32-bit shift and arithmetic operations
Speed of LZMA decompression mostly depends from CPU speed. Speed of LZMA decompressing mostly depends from CPU speed.
Memory speed has no big meaning. But if your CPU has small data cache, Memory speed has no big meaning. But if your CPU has small data cache,
overall weight of memory speed will slightly increase. overall weight of memory speed will slightly increase.
@@ -351,133 +355,211 @@ Offset Size Description
ANSI-C LZMA Decoder ANSI-C LZMA Decoder
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
To use ANSI-C LZMA Decoder you need to files: To compile ANSI-C LZMA Decoder you can use one of the following files sets:
LzmaDecode.h and one of the following two files: 1) LzmaDecode.h + LzmaDecode.c + LzmaTest.c (fastest version)
1) LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version) 2) LzmaDecode.h + LzmaDecodeSize.c + LzmaTest.c (old size-optimized version)
2) LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version) 3) LzmaStateDecode.h + LzmaStateDecode.c + LzmaStateTest.c (zlib-like interface)
use LzmaDecode.c, if you need fastest code.
Memory requirements for LZMA decoding Memory requirements for LZMA decoding
------------------------------------- -------------------------------------
LZMA decoder doesn't allocate memory itself, so you must LZMA decoder doesn't allocate memory itself, so you must
calculate required memory, allocate it and send it to LZMA. allocate memory and send it to LZMA.
Stack usage of LZMA function for local variables is not Stack usage of LZMA decoding function for local variables is not
larger than 200 bytes. larger than 200 bytes.
Memory requirements for decompression depend
from interface that you want to use:
a) Memory to memory decompression:
M1 = (inputSize + outputSize + lzmaInternalSize).
b) Decompression with buffering:
M2 = (inputBufferSize + outputBufferSize + dictionarySize + lzmaInternalSize)
How To decompress data How To decompress data
---------------------- ----------------------
1) Read first byte of properties for LZMA compressed stream, LZMA Decoder (ANSI-C version) now supports 5 interfaces:
check that it has correct value and calculate three 1) Single-call Decompressing
LZMA property variables: 2) Single-call Decompressing with input stream callback
3) Multi-call Decompressing with output buffer
4) Multi-call Decompressing with input callback and output buffer
5) Multi-call State Decompressing (zlib-like interface)
int lc, lp, pb; Variant-5 is similar to Variant-4, but Variant-5 doesn't use callback functions.
unsigned char prop0 = properties[0];
if (prop0 >= (9*5*5))
{
sprintf(rs + strlen(rs), "\n properties error");
return 1;
}
for (pb = 0; prop0 >= (9 * 5);
pb++, prop0 -= (9 * 5));
for (lp = 0; prop0 >= 9;
lp++, prop0 -= 9);
lc = prop0;
2) Calculate required amount for LZMA lzmaInternalSize: Decompressing steps
-------------------
lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * 1) read LZMA properties (5 bytes):
sizeof(CProb) unsigned char properties[LZMA_PROPERTIES_SIZE];
LZMA_BASE_SIZE = 1846 2) read uncompressed size (8 bytes, little-endian)
LZMA_LIT_SIZE = 768
3) Decode properties:
CLzmaDecoderState state; /* it's 24-140 bytes structure, if int is 32-bit */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return PrintError(rs, "Incorrect stream properties");
4) Allocate memory block for internal Structures:
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return PrintError(rs, kCantAllocateMessage);
LZMA decoder uses array of CProb variables as internal structure. LZMA decoder uses array of CProb variables as internal structure.
By default, CProb is (unsigned short) By default, CProb is unsigned_short. But you can define _LZMA_PROB32 to make
But you can define _LZMA_PROB32 to make it (unsigned int) it unsigned_int. It can increase speed on some 32-bit CPUs, but memory
It can increase speed on some 32-bit CPUs, but memory usage will usage will be doubled in that case.
be doubled in that case.
2b) If you use Decompression with buffering, add 100 bytes to 5) Main Decompressing
lzmaInternalSize:
#ifdef _LZMA_OUT_READ
lzmaInternalSize += 100;
#endif
3) Allocate that memory with malloc or some other function: You must use one of the following interfaces:
lzmaInternalData = malloc(lzmaInternalSize); 5.1 Single-call Decompressing
-----------------------------
When to use: RAM->RAM decompressing
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: no defines
Memory Requirements:
- Input buffer: compressed size
- Output buffer: uncompressed size
- LZMA Internal Structures (~16 KB for default settings)
Interface:
int res = LzmaDecode(&state,
inStream, compressedSize, &inProcessed,
outStream, outSize, &outProcessed);
4) Decompress data: 5.2 Single-call Decompressing with input stream callback
--------------------------------------------------------
When to use: File->RAM or Flash->RAM decompressing.
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: _LZMA_IN_CB
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
- Output buffer: uncompressed size
- LZMA Internal Structures (~16 KB for default settings)
4a) If you use simple memory to memory decompression: Interface:
typedef struct _CBuffer
{
ILzmaInCallback InCallback;
FILE *File;
unsigned char Buffer[kInBufferSize];
} CBuffer;
int result = LzmaDecode(lzmaInternalData, lzmaInternalSize, int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
lc, lp, pb, {
unsigned char *inStream, unsigned int inSize, CBuffer *bo = (CBuffer *)object;
unsigned char *outStream, unsigned int outSize, *buffer = bo->Buffer;
&outSizeProcessed); *size = MyReadFile(bo->File, bo->Buffer, kInBufferSize);
return LZMA_RESULT_OK;
}
4b) If you use Decompression with buffering CBuffer g_InBuffer;
4.1) Read dictionary size from properties g_InBuffer.File = inFile;
g_InBuffer.InCallback.Read = LzmaReadCompressed;
int res = LzmaDecode(&state,
&g_InBuffer.InCallback,
outStream, outSize, &outProcessed);
unsigned int dictionarySize = 0;
int i;
for (i = 0; i < 4; i++)
dictionarySize += (unsigned int)(b) << (i * 8);
4.2) Allocate memory for dictionary 5.3 Multi-call decompressing with output buffer
-----------------------------------------------
When to use: RAM->File decompressing
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: _LZMA_OUT_READ
Memory Requirements:
- Input buffer: compressed size
- Buffer for output stream: any size (for example, 16 KB)
- LZMA Internal Structures (~16 KB for default settings)
- LZMA dictionary (dictionary size is encoded in stream properties)
Interface:
unsigned char *dictionary = malloc(dictionarySize); state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
4.3) Initialize LZMA decoder: LzmaDecoderInit(&state);
do
{
LzmaDecode(&state,
inBuffer, inAvail, &inProcessed,
g_OutBuffer, outAvail, &outProcessed);
inAvail -= inProcessed;
inBuffer += inProcessed;
}
while you need more bytes
LzmaDecoderInit((unsigned char *)lzmaInternalData, lzmaInternalSize, see LzmaTest.c for more details.
lc, lp, pb,
dictionary, dictionarySize,
&bo.ReadCallback);
4.4) In loop call LzmaDecoderCode function:
for (nowPos = 0; nowPos < outSize;) 5.4 Multi-call decompressing with input callback and output buffer
{ ------------------------------------------------------------------
unsigned int blockSize = outSize - nowPos; When to use: File->File decompressing
unsigned int kBlockSize = 0x10000; Compile files: LzmaDecode.h, LzmaDecode.c
if (blockSize > kBlockSize) Compile defines: _LZMA_IN_CB, _LZMA_OUT_READ
blockSize = kBlockSize; Memory Requirements:
res = LzmaDecode((unsigned char *)lzmaInternalData, - Buffer for input stream: any size (for example, 16 KB)
((unsigned char *)outStream) + nowPos, blockSize, &outSizeProcessed); - Buffer for output stream: any size (for example, 16 KB)
if (res != 0) - LZMA Internal Structures (~16 KB for default settings)
{ - LZMA dictionary (dictionary size is encoded in stream properties)
printf("\nerror = %d\n", res);
break; Interface:
}
nowPos += outSizeProcessed; state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
if (outSizeProcessed == 0)
{ LzmaDecoderInit(&state);
outSize = nowPos; do
break; {
} LzmaDecode(&state,
} &bo.InCallback,
g_OutBuffer, outAvail, &outProcessed);
}
while you need more bytes
see LzmaTest.c for more details:
5.5 Multi-call State Decompressing (zlib-like interface)
------------------------------------------------------------------
When to use: file->file decompressing
Compile files: LzmaStateDecode.h, LzmaStateDecode.c
Compile defines:
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
- Buffer for output stream: any size (for example, 16 KB)
- LZMA Internal Structures (~16 KB for default settings)
- LZMA dictionary (dictionary size is encoded in stream properties)
Interface:
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
LzmaDecoderInit(&state);
do
{
res = LzmaDecode(&state,
inBuffer, inAvail, &inProcessed,
g_OutBuffer, outAvail, &outProcessed,
finishDecoding);
inAvail -= inProcessed;
inBuffer += inProcessed;
}
while you need more bytes
see LzmaStateTest.c for more details:
6) Free all allocated blocks
Note
----
LzmaDecodeSize.c is size-optimized version of LzmaDecode.c.
But compiled code of LzmaDecodeSize.c can be larger than
compiled code of LzmaDecode.c. So it's better to use
LzmaDecode.c in most cases.
EXIT codes EXIT codes
@@ -487,7 +569,6 @@ LZMA decoder can return one of the following codes:
#define LZMA_RESULT_OK 0 #define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1 #define LZMA_RESULT_DATA_ERROR 1
#define LZMA_RESULT_NOT_ENOUGH_MEM 2
If you use callback function for input data and you return some If you use callback function for input data and you return some
error code, LZMA Decoder also returns that code. error code, LZMA Decoder also returns that code.
@@ -504,6 +585,7 @@ _LZMA_OUT_READ - Use read function for output data
_LZMA_LOC_OPT - Enable local speed optimizations inside code. _LZMA_LOC_OPT - Enable local speed optimizations inside code.
_LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version). _LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version).
_LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version) _LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version)
and LzmaStateDecode.c
_LZMA_PROB32 - It can increase speed on some 32-bit CPUs, _LZMA_PROB32 - It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case but memory usage will be doubled in that case
@@ -511,15 +593,8 @@ _LZMA_PROB32 - It can increase speed on some 32-bit CPUs,
_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler _LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler
and long is 32-bit. and long is 32-bit.
_LZMA_SYSTEM_SIZE_T - Define it if you want to use system's size_t.
NOTES You can use it to enable 64-bit sizes supporting
-----
1) please note that LzmaTest.c doesn't free allocated memory in some cases.
But in your real applicaions you must free memory after decompression.
2) All numbers above were calculated for case when int is not more than
32-bit in your compiler. If in your compiler int is 64-bit or larger
probably LZMA can require more memory for some structures.
@@ -540,5 +615,3 @@ and it will use only bt4 match finder.
http://www.7-zip.org http://www.7-zip.org
http://www.7-zip.org/support.html http://www.7-zip.org/support.html

View File

@@ -1,4 +1,4 @@
7-Zip 4.20 Sources 7-Zip 4.23 Sources
------------------ ------------------
7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP. 7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP.

View File

@@ -158,6 +158,7 @@ public:
_mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir); _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
return (!_mustBeDeleted); return (!_mustBeDeleted);
} }
void DisableDeleting() { _mustBeDeleted = false; }
}; };
#ifdef _UNICODE #ifdef _UNICODE
@@ -179,6 +180,7 @@ public:
_mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir); _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
return (!_mustBeDeleted); return (!_mustBeDeleted);
} }
void DisableDeleting() { _mustBeDeleted = false; }
}; };
#endif #endif

View File

@@ -12,13 +12,12 @@ CGlobal::~CGlobal()
Free(); Free();
} }
// aFlags = GMEM_MOVEABLE bool CGlobal::Alloc(UINT flags, SIZE_T size)
bool CGlobal::Alloc(UINT aFlags, DWORD aSize)
{ {
HGLOBAL aNewBlock = ::GlobalAlloc(aFlags, aSize); HGLOBAL newBlock = ::GlobalAlloc(flags, size);
if (aNewBlock == NULL) if (newBlock == NULL)
return false; return false;
m_MemoryHandle = aNewBlock; m_MemoryHandle = newBlock;
return true; return true;
} }
@@ -30,11 +29,17 @@ bool CGlobal::Free()
return (m_MemoryHandle == NULL); return (m_MemoryHandle == NULL);
} }
void CGlobal::Attach(HGLOBAL hGlobal)
{
Free();
m_MemoryHandle = hGlobal;
}
HGLOBAL CGlobal::Detach() HGLOBAL CGlobal::Detach()
{ {
HGLOBAL aHandle = m_MemoryHandle; HGLOBAL h = m_MemoryHandle;
m_MemoryHandle = NULL; m_MemoryHandle = NULL;
return aHandle; return h;
} }
LPVOID CGlobal::Lock() const LPVOID CGlobal::Lock() const
@@ -47,12 +52,12 @@ void CGlobal::Unlock() const
::GlobalUnlock(m_MemoryHandle); ::GlobalUnlock(m_MemoryHandle);
} }
bool CGlobal::ReAlloc(DWORD aSize) bool CGlobal::ReAlloc(SIZE_T size)
{ {
HGLOBAL aNewBlock = ::GlobalReAlloc(m_MemoryHandle, aSize, GMEM_MOVEABLE); HGLOBAL newBlock = ::GlobalReAlloc(m_MemoryHandle, size, GMEM_MOVEABLE);
if (aNewBlock == NULL) if (newBlock == NULL)
return false; return false;
m_MemoryHandle = aNewBlock; m_MemoryHandle = newBlock;
return true; return true;
} }

View File

@@ -10,15 +10,16 @@ class CGlobal
{ {
HGLOBAL m_MemoryHandle; HGLOBAL m_MemoryHandle;
public: public:
CGlobal():m_MemoryHandle(NULL){}; CGlobal(): m_MemoryHandle(NULL){};
~CGlobal(); ~CGlobal();
operator HGLOBAL() const { return m_MemoryHandle; }; operator HGLOBAL() const { return m_MemoryHandle; };
void Attach(HGLOBAL hGlobal);
HGLOBAL Detach(); HGLOBAL Detach();
bool Alloc(UINT aFlags, DWORD aSize); bool Alloc(UINT flags, SIZE_T size);
bool Free(); bool Free();
LPVOID Lock() const; LPVOID Lock() const;
void Unlock() const; void Unlock() const;
bool ReAlloc(DWORD aSize); bool ReAlloc(SIZE_T size);
}; };
@@ -28,9 +29,9 @@ class CGlobalLock
LPVOID m_Pointer; LPVOID m_Pointer;
public: public:
LPVOID GetPointer() const { return m_Pointer; } LPVOID GetPointer() const { return m_Pointer; }
CGlobalLock(HGLOBAL aGlobal): m_Global(aGlobal) CGlobalLock(HGLOBAL hGlobal): m_Global(hGlobal)
{ {
m_Pointer = ::GlobalLock(m_Global); m_Pointer = ::GlobalLock(hGlobal);
}; };
~CGlobalLock() ~CGlobalLock()
{ {