diff --git a/7zip/Archive/7z_C/7zAlloc.c b/7zip/Archive/7z_C/7zAlloc.c index 91c749ad..c5095920 100755 --- a/7zip/Archive/7z_C/7zAlloc.c +++ b/7zip/Archive/7z_C/7zAlloc.c @@ -14,6 +14,8 @@ int g_allocCountTemp = 0; void *SzAlloc(size_t size) { + if (size == 0) + return 0; #ifdef _SZ_ALLOC_DEBUG fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); g_allocCount++; @@ -35,6 +37,8 @@ void SzFree(void *address) void *SzAllocTemp(size_t size) { + if (size == 0) + return 0; #ifdef _SZ_ALLOC_DEBUG fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); g_allocCountTemp++; diff --git a/7zip/Archive/7z_C/7zBuffer.c b/7zip/Archive/7z_C/7zBuffer.c index 365fb646..3c4b71e8 100755 --- a/7zip/Archive/7z_C/7zBuffer.c +++ b/7zip/Archive/7z_C/7zBuffer.c @@ -12,6 +12,11 @@ void SzByteBufferInit(CSzByteBuffer *buffer) int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)) { buffer->Capacity = newCapacity; + if (newCapacity == 0) + { + buffer->Items = 0; + return 1; + } buffer->Items = (Byte *)allocFunc(newCapacity); return (buffer->Items != 0); } diff --git a/7zip/Archive/7z_C/7zDecode.c b/7zip/Archive/7z_C/7zDecode.c index 0eb2ab99..b42ff927 100755 --- a/7zip/Archive/7z_C/7zDecode.c +++ b/7zip/Archive/7z_C/7zDecode.c @@ -114,11 +114,16 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, return SZE_OUTOFMEMORY; #ifdef _LZMA_OUT_READ - state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); - if (state.Dictionary == 0) + if (state.Properties.DictionarySize == 0) + state.Dictionary = 0; + else { - allocMain->Free(state.Probs); - return SZE_OUTOFMEMORY; + state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); + if (state.Dictionary == 0) + { + allocMain->Free(state.Probs); + return SZE_OUTOFMEMORY; + } } LzmaDecoderInit(&state); #endif diff --git a/7zip/Archive/7z_C/7zExtract.c b/7zip/Archive/7z_C/7zExtract.c index b269b15c..6ef872c3 100755 --- a/7zip/Archive/7z_C/7zExtract.c +++ b/7zip/Archive/7z_C/7zExtract.c @@ -45,18 +45,26 @@ SZ_RESULT SzExtract( RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); #ifndef _LZMA_IN_CB - inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); - if (inBuffer == 0) - return SZE_OUTOFMEMORY; + if (packSize != 0) + { + inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); + if (inBuffer == 0) + return SZE_OUTOFMEMORY; + } res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize); if (res == SZ_OK && processedSize != (size_t)packSize) res = SZE_FAIL; #endif if (res == SZ_OK) { - *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize); *outBufferSize = (size_t)unPackSize; - if (*outBuffer != 0) + if (unPackSize != 0) + { + *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize); + if (*outBuffer == 0) + res = SZE_OUTOFMEMORY; + } + if (res == SZ_OK) { size_t outRealSize; res = SzDecode(db->Database.PackSizes + @@ -81,8 +89,6 @@ SZ_RESULT SzExtract( res = SZE_FAIL; } } - else - res = SZE_OUTOFMEMORY; } #ifndef _LZMA_IN_CB allocTemp->Free(inBuffer); diff --git a/7zip/Archive/7z_C/7zIn.c b/7zip/Archive/7z_C/7zIn.c index 1e9f88e5..c7d65e2a 100755 --- a/7zip/Archive/7z_C/7zIn.c +++ b/7zip/Archive/7z_C/7zIn.c @@ -45,6 +45,18 @@ CFileSize GetFilePackSize(int fileIndex) const */ +SZ_RESULT MySzInAlloc(void **p, size_t size, void * (*allocFunc)(size_t size)) +{ + if (size == 0) + *p = 0; + else + { + *p = allocFunc(size); + RINOM(*p); + } + return SZ_OK; +} + SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) { UInt32 startPos = 0; @@ -52,16 +64,14 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) UInt32 i; UInt32 folderIndex = 0; UInt32 indexInFolder = 0; - db->FolderStartPackStreamIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32)); - RINOM(db->FolderStartPackStreamIndex); + RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc)); for(i = 0; i < db->Database.NumFolders; i++) { db->FolderStartPackStreamIndex[i] = startPos; startPos += db->Database.Folders[i].NumPackStreams; } - db->PackStreamStartPositions = (CFileSize *)allocFunc(db->Database.NumPackStreams * sizeof(CFileSize)); - RINOM(db->PackStreamStartPositions); + RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc)); for(i = 0; i < db->Database.NumPackStreams; i++) { @@ -69,11 +79,8 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) startPosSize += db->Database.PackSizes[i]; } - db->FolderStartFileIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32)); - RINOM(db->FolderStartFileIndex); - - db->FileIndexToFolderIndexMap = (UInt32 *)allocFunc(db->Database.NumFiles * sizeof(UInt32)); - RINOM(db->FileIndexToFolderIndexMap); + RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc)); + RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), allocFunc)); for (i = 0; i < db->Database.NumFiles; i++) { @@ -378,8 +385,7 @@ SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, int **v, void * (*alloc Byte b = 0; Byte mask = 0; size_t i; - *v = (int *)allocFunc(numItems * sizeof(int)); - RINOM(*v); + RINOK(MySzInAlloc((void **)v, numItems * sizeof(int), allocFunc)); for(i = 0; i < numItems; i++) { if (mask == 0) @@ -400,8 +406,7 @@ SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, int **v, void * (*allo RINOK(SzReadByte(sd, &allAreDefined)); if (allAreDefined == 0) return SzReadBoolVector(sd, numItems, v, allocFunc); - *v = (int *)allocFunc(numItems * sizeof(int)); - RINOM(*v); + RINOK(MySzInAlloc((void **)v, numItems * sizeof(int), allocFunc)); for(i = 0; i < numItems; i++) (*v)[i] = 1; return SZ_OK; @@ -416,8 +421,7 @@ SZ_RESULT SzReadHashDigests( { size_t i; RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc)); - *digests = (UInt32 *)allocFunc(numItems * sizeof(UInt32)); - RINOM(*digests); + RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), allocFunc)); for(i = 0; i < numItems; i++) if ((*digestsDefined)[i]) { @@ -440,8 +444,8 @@ SZ_RESULT SzReadPackInfo( RINOK(SzReadNumber32(sd, numPackStreams)); RINOK(SzWaitAttribute(sd, k7zIdSize)); - *packSizes = (CFileSize *)allocFunc((size_t)*numPackStreams * sizeof(CFileSize)); - RINOM(*packSizes); + + RINOK(MySzInAlloc((void **)packSizes, (size_t)*numPackStreams * sizeof(CFileSize), allocFunc)); for(i = 0; i < *numPackStreams; i++) { @@ -463,10 +467,8 @@ SZ_RESULT SzReadPackInfo( } if (*packCRCsDefined == 0) { - *packCRCsDefined = (int *)allocFunc((size_t)*numPackStreams * sizeof(int)); - RINOM(*packCRCsDefined); - *packCRCs = (UInt32 *)allocFunc((size_t)*numPackStreams * sizeof(UInt32)); - RINOM(*packCRCs); + RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(int), allocFunc)); + RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), allocFunc)); for(i = 0; i < *numPackStreams; i++) { (*packCRCsDefined)[i] = 0; @@ -494,8 +496,8 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( RINOK(SzReadNumber32(sd, &numCoders)); folder->NumCoders = numCoders; - folder->Coders = (CCoderInfo *)allocFunc((size_t)numCoders * sizeof(CCoderInfo)); - RINOM(folder->Coders); + RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc)); + for (i = 0; i < numCoders; i++) SzCoderInfoInit(folder->Coders + i); @@ -550,9 +552,9 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( numBindPairs = numOutStreams - 1; folder->NumBindPairs = numBindPairs; - folder->BindPairs = (CBindPair *)allocFunc((size_t)numBindPairs * sizeof(CBindPair)); - RINOM(folder->BindPairs); - + + RINOK(MySzInAlloc((void **)&folder->BindPairs, (size_t)numBindPairs * sizeof(CBindPair), allocFunc)); + for (i = 0; i < numBindPairs; i++) { CBindPair *bindPair = folder->BindPairs + i;; @@ -563,8 +565,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( numPackedStreams = numInStreams - (UInt32)numBindPairs; folder->NumPackStreams = numPackedStreams; - folder->PackStreams = (UInt32 *)allocFunc((size_t)numPackedStreams * sizeof(UInt32)); - RINOM(folder->PackStreams); + RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), allocFunc)); if (numPackedStreams == 1) { @@ -598,8 +599,9 @@ SZ_RESULT SzReadUnPackInfo( { RINOK(SzReadSwitch(sd)); - *folders = (CFolder *)allocFunc((size_t)*numFolders * sizeof(CFolder)); - RINOM(*folders); + + RINOK(MySzInAlloc((void **)folders, (size_t)*numFolders * sizeof(CFolder), allocFunc)); + for(i = 0; i < *numFolders; i++) SzFolderInit((*folders) + i); @@ -617,8 +619,7 @@ SZ_RESULT SzReadUnPackInfo( CFolder *folder = (*folders) + i; UInt32 numOutStreams = SzFolderGetNumOutStreams(folder); - folder->UnPackSizes = (CFileSize *)allocFunc((size_t)numOutStreams * sizeof(CFileSize)); - RINOM(folder->UnPackSizes); + RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc)); for(j = 0; j < numOutStreams; j++) { @@ -698,14 +699,21 @@ SZ_RESULT SzReadSubStreamsInfo( RINOK(SzSkeepData(sd)); } - *unPackSizes = (CFileSize *)allocFunc((size_t)*numUnPackStreams * sizeof(CFileSize)); - RINOM(*unPackSizes); - - *digestsDefined = (int *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(int)); - RINOM(*digestsDefined); - - *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); - RINOM(*digests); + if (*numUnPackStreams == 0) + { + *unPackSizes = 0; + *digestsDefined = 0; + *digests = 0; + } + else + { + *unPackSizes = (CFileSize *)allocFunc((size_t)*numUnPackStreams * sizeof(CFileSize)); + RINOM(*unPackSizes); + *digestsDefined = (int *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(int)); + RINOM(*digestsDefined); + *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); + RINOM(*digests); + } for(i = 0; i < numFolders; i++) { @@ -880,8 +888,7 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, len += numAdds; } - file->Name = (char *)allocFunc((size_t)len * sizeof(char)); - RINOM(file->Name); + RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc)); len = 0; while(2 <= sd->Size) @@ -968,8 +975,8 @@ SZ_RESULT SzReadHeader2( RINOK(SzReadNumber32(sd, &numFiles)); db->Database.NumFiles = numFiles; - files = (CFileItem *)allocTemp->Alloc((size_t)numFiles * sizeof(CFileItem)); - RINOM(files); + RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocTemp->Alloc)); + db->Database.Files = files; for(i = 0; i < numFiles; i++) SzFileInit(files + i); @@ -1136,9 +1143,8 @@ SZ_RESULT SzReadAndDecodePackedStreams2( for (i = 0; i < db->NumPackStreams; i++) packSize += db->PackSizes[i]; - *inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); - RINOM(*inBuffer); - + RINOK(MySzInAlloc((void **)inBuffer, (size_t)packSize, allocTemp->Alloc)); + RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize)); #endif diff --git a/7zip/Archive/7z_C/7zMain.c b/7zip/Archive/7z_C/7zMain.c index 6320bd18..425e57b3 100755 --- a/7zip/Archive/7z_C/7zMain.c +++ b/7zip/Archive/7z_C/7zMain.c @@ -1,7 +1,7 @@ /* 7zMain.c Test application for 7z Decoder -LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-09-24) +LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02) */ #include @@ -71,7 +71,7 @@ int main(int numargs, char *args[]) ISzAlloc allocImp; ISzAlloc allocTempImp; - printf("\n7z ANSI-C Decoder 4.16 Copyright (c) 1999-2005 Igor Pavlov 2005-03-29\n"); + printf("\n7z ANSI-C Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); if (numargs == 1) { printf( @@ -146,7 +146,7 @@ int main(int numargs, char *args[]) size_t outSizeProcessed; CFileItem *f = db.Database.Files + i; printf(testCommand ? - "Tesing ": + "Testing ": "Extracting"); printf(" %s", f->Name); res = SzExtract(&archiveStream.InStream, &db, i, diff --git a/7zip/Archive/Cab/CabInBuffer.cpp b/7zip/Archive/Cab/CabInBuffer.cpp index de759a58..c429033c 100755 --- a/7zip/Archive/Cab/CabInBuffer.cpp +++ b/7zip/Archive/Cab/CabInBuffer.cpp @@ -152,12 +152,12 @@ HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) if (m_NumReadBytesInBuffer != packSize) throw "bad block"; - // Now I don't remember why (checkSum == 0) check is disbaled // Cab specification: // checkSum: May be set to zero if the checksum is not supplied. // but seems it's stupid rule. if (checkSum == 0) dataAreCorrect = true; + else { CCheckSum checkSumCalc; checkSumCalc.Update(m_Buffer, packSize); diff --git a/7zip/Archive/Lzh/DllExports.cpp b/7zip/Archive/Lzh/DllExports.cpp new file mode 100755 index 00000000..567d4bf8 --- /dev/null +++ b/7zip/Archive/Lzh/DllExports.cpp @@ -0,0 +1,72 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "LzhHandler.h" + +// {23170F69-40C1-278A-1000-0001100E0000} +DEFINE_GUID(CLSID_CLzhHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0E, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CLzhHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NLzh::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Lzh"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CLzhHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"lzh lha"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { '-', 'l' }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/7zip/Archive/Lzh/Lzh.def b/7zip/Archive/Lzh/Lzh.def new file mode 100755 index 00000000..e240b3f2 --- /dev/null +++ b/7zip/Archive/Lzh/Lzh.def @@ -0,0 +1,7 @@ +; Arj.def + +LIBRARY Arj.dll + +EXPORTS + CreateObject PRIVATE + GetHandlerProperty PRIVATE diff --git a/7zip/Archive/Lzh/Lzh.dsp b/7zip/Archive/Lzh/Lzh.dsp new file mode 100755 index 00000000..9f5b21b0 --- /dev/null +++ b/7zip/Archive/Lzh/Lzh.dsp @@ -0,0 +1,317 @@ +# Microsoft Developer Studio Project File - Name="Lzh" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Lzh - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lzh.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lzh.mak" CFG="Lzh - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Lzh - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Lzh - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Lzh - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\lzh.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Lzh - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\lzh.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Lzh - Win32 Release" +# Name "Lzh - Win32 Debug" +# Begin Group "spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\LzhCRC.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhCRC.h +# End Source File +# Begin Source File + +SOURCE=.\LzhHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhHandler.h +# End Source File +# Begin Source File + +SOURCE=.\LzhHeader.h +# End Source File +# Begin Source File + +SOURCE=.\LzhIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhIn.h +# End Source File +# Begin Source File + +SOURCE=.\LzhItem.h +# End Source File +# Begin Source File + +SOURCE=.\LzhOutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhOutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Codecs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzh\LzhDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzh\LzhDecoder.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\lzh.ico +# End Source File +# End Target +# End Project diff --git a/7zip/Archive/Lzh/Lzh.dsw b/7zip/Archive/Lzh/Lzh.dsw new file mode 100755 index 00000000..41ab2218 --- /dev/null +++ b/7zip/Archive/Lzh/Lzh.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lzh"=.\lzh.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Archive/Lzh/LzhCRC.cpp b/7zip/Archive/Lzh/LzhCRC.cpp new file mode 100755 index 00000000..f11564a5 --- /dev/null +++ b/7zip/Archive/Lzh/LzhCRC.cpp @@ -0,0 +1,43 @@ +// LzhCRC.cpp + +#include "StdAfx.h" + +#include "LzhCRC.h" + +namespace NArchive { +namespace NLzh { + +static const UInt16 kCRCPoly = 0xA001; + +UInt16 CCRC::Table[256]; + +void CCRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCRCPoly; + else + r >>= 1; + CCRC::Table[i] = (UInt16)r; + } +} + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } +} g_CRCTableInit; + +void CCRC::Update(const void *data, size_t size) +{ + UInt16 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0; size--, p++) + v = Table[((Byte)(v)) ^ *p] ^ (v >> 8); + _value = v; +} + +}} diff --git a/7zip/Archive/Lzh/LzhCRC.h b/7zip/Archive/Lzh/LzhCRC.h new file mode 100755 index 00000000..22512563 --- /dev/null +++ b/7zip/Archive/Lzh/LzhCRC.h @@ -0,0 +1,27 @@ +// LzhCRC.h + +#ifndef __LZH_CRC_H +#define __LZH_CRC_H + +#include +#include "Common/Types.h" + +namespace NArchive { +namespace NLzh { + +class CCRC +{ + UInt32 _value; +public: + static UInt16 Table[256]; + static void InitTable(); + + CCRC(): _value(0){}; + void Init() { _value = 0; } + void Update(const void *data, size_t size); + UInt16 GetDigest() const { return _value; } +}; + +}} + +#endif diff --git a/7zip/Archive/Lzh/LzhHandler.cpp b/7zip/Archive/Lzh/LzhHandler.cpp new file mode 100755 index 00000000..9502e5e9 --- /dev/null +++ b/7zip/Archive/Lzh/LzhHandler.cpp @@ -0,0 +1,458 @@ +// LzhHandler.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "LzhHandler.h" +#include "LzhOutStreamWithCRC.h" + +#include "../../ICoder.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Lzh/LzhDecoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NLzh{ + +struct COsPair +{ + Byte Id; + const wchar_t *Name; +}; + +COsPair g_OsPairs[] = +{ + { 'M', L"MS-DOS" }, + { '2', L"OS/2" }, + { '9', L"OS9" }, + { 'K', L"OS/68K" }, + { '3', L"OS/386" }, + { 'H', L"HUMAN" }, + { 'U', L"UNIX" }, + { 'C', L"CP/M" }, + { 'F', L"FLEX" }, + { 'm', L"Mac" }, + { 'R', L"Runser" }, + { 'T', L"TownsOS" }, + { 'X', L"XOSK" }, + { 'w', L"Windows95" }, + { 'W', L"WindowsNT" }, + { 0, L"MS-DOS" }, + { 'J', L"Java VM" } +}; + +const wchar_t *kUnknownOS = L"Unknown"; + +const int kNumHostOSes = sizeof(g_OsPairs) / sizeof(g_OsPairs[0]); + +static const wchar_t *GetOS(Byte osId) +{ + for (int i = 0; i < kNumHostOSes; i++) + if (g_OsPairs[i].Id == osId) + return g_OsPairs[i].Name; + return kUnknownOS; +}; + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + + // { NULL, kpidCommented, VT_BOOL}, + + { NULL, kpidCRC, VT_UI4}, + + { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR} + +}; + + +CHandler::CHandler() +{} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CItemEx &item = _items[index]; + switch(propID) + { + case kpidPath: + { + const UString s = NItemName::GetOSName2(MultiByteToUnicodeString(item.GetName(), CP_OEMCP)); + if (!s.IsEmpty()) + propVariant = s; + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.Size; + break; + case kpidPackedSize: + propVariant = item.PackSize; + break; + case kpidLastWriteTime: + { + FILETIME utcFileTime; + UInt32 unixTime; + if (item.GetUnixTime(unixTime)) + { + NTime::UnixTimeToFileTime(unixTime, utcFileTime); + } + else + { + FILETIME localFileTime; + if (DosTimeToFileTime(item.ModifiedTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + propVariant = utcFileTime; + break; + } + /* + case kpidAttributes: + propVariant = (UInt32)item.Attributes; + break; + case kpidCommented: + propVariant = item.IsCommented(); + break; + */ + case kpidCRC: + propVariant = (UInt32)item.CRC; + break; + case kpidMethod: + { + wchar_t method2[kMethodIdSize + 1]; + method2[kMethodIdSize] = 0; + for (int i = 0; i < kMethodIdSize; i++) + method2[i] = item.Method[i]; + propVariant = method2; + break; + } + case kpidHostOS: + propVariant = GetOS(item.OsId); + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +/* +class CPropgressImp: public CProgressVirt +{ +public: + CMyComPtr Callback; + STDMETHOD(SetCompleted)(const UInt64 *numFiles); +}; + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (Callback) + return Callback->SetCompleted(numFiles, NULL); + return S_OK; +} +*/ + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + try + { + _items.Clear(); + CInArchive archive; + RINOK(archive.Open(inStream)); + if (callback != NULL) + { + RINOK(callback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); + } + while(true) + { + CItemEx itemInfo; + bool filled; + HRESULT result = archive.GetNextItem(filled, itemInfo); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(itemInfo); + archive.Skeep(itemInfo.PackSize); + if (callback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); + } + } + if (_items.IsEmpty()) + return S_FALSE; + + _stream = inStream; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + return S_OK; +} + + + +////////////////////////////////////// +// CHandler::DecompressItems + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (testModeSpec != 0); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += itemInfo.Size; + totalPacked += itemInfo.PackSize; + } + extractCallback->SetTotal(totalUnPacked); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + + NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec; + CMyComPtr lzhDecoder; + CMyComPtr lzh1Decoder; + CMyComPtr arj2Decoder; + CMyComPtr copyCoder; + + for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) + { + currentItemUnPacked = 0; + currentItemPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + const CItemEx &itemInfo = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if(itemInfo.IsDirectory()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + continue; + } + + if (!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + currentItemUnPacked = itemInfo.Size; + currentItemPacked = itemInfo.PackSize; + + { + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->Init(realOutStream); + realOutStream.Release(); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + + UInt64 pos; + _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); + + streamSpec->Init(_stream, itemInfo.PackSize); + + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + + HRESULT result; + + if (itemInfo.IsCopyMethod()) + { + if(!copyCoder) + copyCoder = new NCompress::CCopyCoder; + try + { + result = copyCoder->Code(inStream, outStream, NULL, NULL, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + else if (itemInfo.IsLh4GroupMethod()) + { + if(!lzhDecoder) + { + lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; + lzhDecoder = lzhDecoderSpec; + } + try + { + lzhDecoderSpec->SetDictionary(itemInfo.GetNumDictBits()); + result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + /* + else if (itemInfo.IsLh1GroupMethod()) + { + if(!lzh1Decoder) + { + lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; + lzh1Decoder = lzh1DecoderSpec; + } + try + { + lzh1DecoderSpec->SetDictionary(itemInfo.GetNumDictBits()); + result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + */ + else + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + bool crcOK = (outStreamSpec->GetCRC() == itemInfo.CRC); + outStream.Release(); + if(crcOK) + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + else + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + } + } + return S_OK; + COM_TRY_END +} + + +}} diff --git a/7zip/Archive/Lzh/LzhHandler.h b/7zip/Archive/Lzh/LzhHandler.h new file mode 100755 index 00000000..2dc89494 --- /dev/null +++ b/7zip/Archive/Lzh/LzhHandler.h @@ -0,0 +1,47 @@ +// LzhHandler.h + +#ifndef __LZH_HANDLER_H +#define __LZH_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "LzhIn.h" + +namespace NArchive { +namespace NLzh { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + CHandler(); +private: + CObjectVector _items; + CMyComPtr _stream; +}; + +}} + +#endif diff --git a/7zip/Archive/Lzh/LzhHeader.h b/7zip/Archive/Lzh/LzhHeader.h new file mode 100755 index 00000000..845b9a21 --- /dev/null +++ b/7zip/Archive/Lzh/LzhHeader.h @@ -0,0 +1,19 @@ +// Archive/Lzh/Header.h + +#ifndef __ARCHIVE_LZH_HEADER_H +#define __ARCHIVE_LZH_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NLzh { + +const int kMethodIdSize = 5; + +const Byte kExtIdFileName = 0x01; +const Byte kExtIdDirName = 0x02; +const Byte kExtIdUnixTime = 0x54; + +}} + +#endif diff --git a/7zip/Archive/Lzh/LzhIn.cpp b/7zip/Archive/Lzh/LzhIn.cpp new file mode 100755 index 00000000..f9b5daff --- /dev/null +++ b/7zip/Archive/Lzh/LzhIn.cpp @@ -0,0 +1,169 @@ +/ Archive/arj/InEngine.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Buffer.h" +#include "Common/CRC.h" + +#include "LzhIn.h" + +namespace NArchive { +namespace NLzh { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + RINOK(m_Stream->Read(data, size, &processedSize)); + m_Position += processedSize; + return S_OK; +} + +HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size) +{ + UInt32 processedSize; + RINOK(ReadBytes(data, size, processedSize)); + return (processedSize == size) ? S_OK: S_FALSE; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + m_Stream = inStream; + return S_OK; +} + +static const Byte *ReadUInt32(const Byte *p, UInt32 &v) +{ + v = 0; + for (int i = 0; i < 4; i++) + v |= ((UInt32)(*p++) << (i * 8)); + return p; +} + +static const Byte *ReadUInt16(const Byte *p, UInt16 &v) +{ + v = 0; + for (int i = 0; i < 2; i++) + v |= ((UInt16)(*p++) << (i * 8)); + return p; +} + +static const Byte *ReadString(const Byte *p, size_t size, AString &s) +{ + s.Empty(); + for (size_t i = 0; i < size; i++) + { + char c = p[i]; + if (c == 0) + break; + s += c; + } + return p + size; +} + +static Byte CalcSum(const Byte *data, size_t size) +{ + Byte sum = 0; + for (size_t i = 0; i < size; i++) + sum += data[i]; + return sum; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + filled = false; + + UInt32 processedSize; + Byte startHeader[2]; + RINOK(ReadBytes(startHeader, 2, processedSize)) + if (processedSize == 0) + return S_OK; + if (processedSize == 1) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + if (startHeader[0] == 0 && startHeader[1] == 0) + return S_OK; + + Byte header[256]; + const UInt32 kBasicPartSize = 22; + RINOK(ReadBytes(header, kBasicPartSize, processedSize)); + if (processedSize != kBasicPartSize) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + + const Byte *p = header; + memmove(item.Method, p, kMethodIdSize); + if (!item.IsValidMethod()) + return S_OK; + p += kMethodIdSize; + p = ReadUInt32(p, item.PackSize); + p = ReadUInt32(p, item.Size); + p = ReadUInt32(p, item.ModifiedTime); + item.Attributes = *p++; + item.Level = *p++; + if (item.Level > 2) + return S_FALSE; + UInt32 headerSize; + if (item.Level < 2) + { + headerSize = startHeader[0]; + if (headerSize < kBasicPartSize) + return S_FALSE; + UInt32 remain = headerSize - kBasicPartSize; + RINOK(CheckReadBytes(header + kBasicPartSize, remain)); + if (startHeader[1] != CalcSum(header, headerSize)) + return S_FALSE; + size_t nameLength = *p++; + if ((p - header) + nameLength + 2 > headerSize) + return S_FALSE; + p = ReadString(p, nameLength, item.Name); + } + else + headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8); + p = ReadUInt16(p, item.CRC); + if (item.Level != 0) + { + if (item.Level == 2) + { + RINOK(CheckReadBytes(header + kBasicPartSize, 2)); + } + if ((size_t)(p - header) + 3 > headerSize) + return S_FALSE; + item.OsId = *p++; + UInt16 nextSize; + p = ReadUInt16(p, nextSize); + while (nextSize != 0) + { + if (nextSize < 3) + return S_FALSE; + if (item.Level == 1) + { + if (item.PackSize < nextSize) + return S_FALSE; + item.PackSize -= nextSize; + } + CExtension ext; + RINOK(CheckReadBytes(&ext.Type, 1)) + nextSize -= 3; + ext.Data.SetCapacity(nextSize); + RINOK(CheckReadBytes((Byte *)ext.Data, nextSize)) + item.Extensions.Add(ext); + Byte hdr2[2]; + RINOK(CheckReadBytes(hdr2, 2)); + ReadUInt16(hdr2, nextSize); + } + } + item.DataPosition = m_Position; + filled = true; + return S_OK; +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) + return E_FAIL; + return S_OK; +} + +}} diff --git a/7zip/Archive/Lzh/LzhIn.h b/7zip/Archive/Lzh/LzhIn.h new file mode 100755 index 00000000..344a133f --- /dev/null +++ b/7zip/Archive/Lzh/LzhIn.h @@ -0,0 +1,29 @@ +// Archive/LzhIn.h + +#ifndef __ARCHIVE_LZHIN_H +#define __ARCHIVE_LZHIN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "LzhItem.h" + +namespace NArchive { +namespace NLzh { + +class CInArchive +{ + CMyComPtr m_Stream; + UInt64 m_Position; + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); + HRESULT CheckReadBytes(void *data, UInt32 size); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); +}; + +}} + +#endif diff --git a/7zip/Archive/Lzh/LzhItem.h b/7zip/Archive/Lzh/LzhItem.h new file mode 100755 index 00000000..36ccb672 --- /dev/null +++ b/7zip/Archive/Lzh/LzhItem.h @@ -0,0 +1,165 @@ +// Archive/LzhItem.h + +#ifndef __ARCHIVE_LZH_ITEM_H +#define __ARCHIVE_LZH_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "Common/Buffer.h" +#include "LzhHeader.h" + +namespace NArchive { +namespace NLzh { + +struct CExtension +{ + Byte Type; + CByteBuffer Data; + AString GetString() const + { + AString s; + for (size_t i = 0; i < Data.GetCapacity(); i++) + { + char c = (char)Data[i]; + if (c == 0) + break; + s += c; + } + return s; + } +}; + +struct CItem +{ +public: + AString Name; + Byte Method[kMethodIdSize]; + UInt32 PackSize; + UInt32 Size; + UInt32 ModifiedTime; + Byte Attributes; + Byte Level; + UInt16 CRC; + Byte OsId; + CObjectVector Extensions; + + bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } + bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } + bool IsDirectory() const {return (IsLhMethod() && Method[3] == 'd'); } + + bool IsCopyMethod() const + { + return (IsLhMethod() && Method[3] == '0') || + (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); + } + + bool IsLh1GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch(Method[3]) + { + case '1': + return true; + } + return false; + } + + bool IsLh4GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch(Method[3]) + { + case '4': + case '5': + case '6': + case '7': + return true; + } + return false; + } + + int GetNumDictBits() const + { + if (!IsLhMethod()) + return 0; + switch(Method[3]) + { + case '1': + return 12; + case '2': + return 13; + case '3': + return 13; + case '4': + return 12; + case '5': + return 13; + case '6': + return 15; + case '7': + return 16; + } + return 0; + } + + int FindExt(Byte type) const + { + for (int i = 0; i < Extensions.Size(); i++) + if (Extensions[i].Type == type) + return i; + return -1; + } + bool GetUnixTime(UInt32 &value) const + { + int index = FindExt(kExtIdUnixTime); + if (index < 0) + return false; + const Byte *data = (const Byte *)(Extensions[index].Data); + value = data[0] | + ((UInt32)data[1] << 8) | + ((UInt32)data[2] << 16) | + ((UInt32)data[3] << 24); + return true; + } + + AString GetDirName() const + { + int index = FindExt(kExtIdDirName); + if (index < 0) + return AString(); + return Extensions[index].GetString(); + } + + AString GetFileName() const + { + int index = FindExt(kExtIdFileName); + if (index < 0) + return Name; + return Extensions[index].GetString(); + } + + AString GetName() const + { + AString dirName = GetDirName(); + dirName.Replace((char)0xFF, '\\'); + if (!dirName.IsEmpty()) + { + char c = dirName[dirName.Length() - 1]; + if (c != '\\' && c != '/') + dirName += '\\'; + } + return dirName + GetFileName(); + } +}; + +class CItemEx: public CItem +{ +public: + UInt64 DataPosition; +}; + +}} + +#endif diff --git a/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp b/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp new file mode 100755 index 00000000..ddefec88 --- /dev/null +++ b/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp @@ -0,0 +1,46 @@ +// LzhOutStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "LzhOutStreamWithCRC.h" + +namespace NArchive { +namespace NLzh { + +STDMETHODIMP COutStreamWithCRC::Write(const void *data, + UInt32 size, UInt32 *processedSize) +{ + HRESULT result; + UInt32 realProcessedSize; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP COutStreamWithCRC::WritePart(const void *data, + UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->WritePart(data, size, &realProcessedSize); + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +}} diff --git a/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/7zip/Archive/Lzh/LzhOutStreamWithCRC.h new file mode 100755 index 00000000..fc5fc1c9 --- /dev/null +++ b/7zip/Archive/Lzh/LzhOutStreamWithCRC.h @@ -0,0 +1,39 @@ +// LzhOutStreamWithCRC.h + +#ifndef __LZHOUTSTREAMWITHCRC_H +#define __LZHOUTSTREAMWITHCRC_H + +#include "LzhCRC.h" +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NLzh { + +class COutStreamWithCRC: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); +private: + CCRC _crc; + CMyComPtr _stream; +public: + void Init(ISequentialOutStream *stream) + { + _stream = stream; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } + void InitCRC() { _crc.Init(); } + +}; + +}} + +#endif diff --git a/7zip/Archive/Lzh/StdAfx.cpp b/7zip/Archive/Lzh/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Archive/Lzh/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Archive/Lzh/StdAfx.h b/7zip/Archive/Lzh/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Archive/Lzh/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Archive/Lzh/lzh.ico b/7zip/Archive/Lzh/lzh.ico new file mode 100755 index 00000000..84dab49c Binary files /dev/null and b/7zip/Archive/Lzh/lzh.ico differ diff --git a/7zip/Archive/Lzh/makefile b/7zip/Archive/Lzh/makefile new file mode 100755 index 00000000..caa61334 --- /dev/null +++ b/7zip/Archive/Lzh/makefile @@ -0,0 +1,63 @@ +PROG = lzh.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +LZH_OBJS = \ + $O\DllExports.obj \ + $O\LzhCRC.obj \ + $O\LzhHandler.obj \ + $O\LzhIn.obj \ + $O\LzhOutStreamWithCRC.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +COMPRESS_LZH_OBJS = \ + $O\LzhDecoder.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(LZH_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_LZH_OBJS) \ + $O\CopyCoder.obj \ + $O\LZOutWindow.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(LZH_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_LZH_OBJS): ../../Compress/Lzh/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) diff --git a/7zip/Archive/Lzh/resource.rc b/7zip/Archive/Lzh/resource.rc new file mode 100755 index 00000000..2870e520 --- /dev/null +++ b/7zip/Archive/Lzh/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Lzh Plugin", "lzh") + +101 ICON "lzh.ico" diff --git a/7zip/Archive/Zip/ZipAddCommon.cpp b/7zip/Archive/Zip/ZipAddCommon.cpp index 8c259c33..26d330fd 100755 --- a/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/7zip/Archive/Zip/ZipAddCommon.cpp @@ -188,7 +188,8 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, { NWindows::NCOM::CPropVariant properties[2] = { - _options.NumPasses, _options.NumFastBytes + _options.NumPasses, + _options.NumFastBytes }; PROPID propIDs[2] = { @@ -196,10 +197,23 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, NCoderPropID::kNumFastBytes }; CMyComPtr setCoderProperties; - RINOK(_compressEncoder.QueryInterface( - IID_ICompressSetCoderProperties, &setCoderProperties)); - setCoderProperties->SetCoderProperties(propIDs, properties, 2); + RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2)); + } else if (method == NFileHeader::NCompressionMethod::kBZip2) + { + NWindows::NCOM::CPropVariant properties[1] = + { + _options.NumPasses + }; + PROPID propIDs[1] = + { + NCoderPropID::kNumPasses, + }; + CMyComPtr setCoderProperties; + RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 1)); } + } CMyComPtr outStreamNew; if (_options.PasswordIsDefined) diff --git a/7zip/Archive/Zip/ZipHandler.cpp b/7zip/Archive/Zip/ZipHandler.cpp index 424a58a0..922a69c7 100755 --- a/7zip/Archive/Zip/ZipHandler.cpp +++ b/7zip/Archive/Zip/ZipHandler.cpp @@ -153,8 +153,6 @@ CHandler::CHandler(): m_ArchiveIsOpen(false) { InitMethodProperties(); - m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kDeflated); - m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); } STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) diff --git a/7zip/Archive/Zip/ZipHandler.h b/7zip/Archive/Zip/ZipHandler.h index f5a97ae2..bb879436 100755 --- a/7zip/Archive/Zip/ZipHandler.h +++ b/7zip/Archive/Zip/ZipHandler.h @@ -58,11 +58,17 @@ private: CObjectVector m_Items; CInArchive m_Archive; bool m_ArchiveIsOpen; - CCompressionMethodMode m_Method; + + int m_Level; + int m_MainMethod; + UInt32 m_NumPasses; + UInt32 m_NumFastBytes; void InitMethodProperties() { - m_Method.NumPasses = 1; - m_Method.NumFastBytes = 32; + m_Level = -1; + m_MainMethod = -1; + m_NumPasses = 0xFFFFFFFF; + m_NumFastBytes = 0xFFFFFFFF; } }; diff --git a/7zip/Archive/Zip/ZipHandlerOut.cpp b/7zip/Archive/Zip/ZipHandlerOut.cpp index 7b7fac4c..e88873e5 100755 --- a/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -22,6 +22,16 @@ using namespace NTime; namespace NArchive { namespace NZip { +static const UInt32 kNumDeflatePassesX1 = 1; +static const UInt32 kNumDeflatePassesX7 = 3; + +static const UInt32 kNumBZip2PassesX1 = 1; +static const UInt32 kNumBZip2PassesX7 = 2; +static const UInt32 kNumBZip2PassesX9 = 7; + +static const UInt32 kNumFastBytesX1 = 32; +static const UInt32 kNumFastBytesX7 = 64; + STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) { *timeType = NFileTimeType::kDOS; @@ -158,34 +168,62 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt CMyComPtr udateCallBack2(updateCallback); udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); } + CCompressionMethodMode options; + if (getTextPassword) { CMyComBSTR password; Int32 passwordIsDefined; RINOK(getTextPassword->CryptoGetTextPassword2( &passwordIsDefined, &password)); - if (m_Method.PasswordIsDefined = IntToBool(passwordIsDefined)) - m_Method.Password = UnicodeStringToMultiByte( - (const wchar_t *)password, CP_OEMCP); + if (options.PasswordIsDefined = IntToBool(passwordIsDefined)) + options.Password = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP); } else - m_Method.PasswordIsDefined = false; + options.PasswordIsDefined = false; + + int level = m_Level; + if (level < 0) + level = 5; + + Byte mainMethod; + if (m_MainMethod < 0) + mainMethod = ((level == 0) ? + NFileHeader::NCompressionMethod::kStored : + NFileHeader::NCompressionMethod::kDeflated); + else + mainMethod = (Byte)m_MainMethod; + options.MethodSequence.Add(mainMethod); + if (mainMethod != NFileHeader::NCompressionMethod::kStored) + options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); + bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) || + (mainMethod == NFileHeader::NCompressionMethod::kDeflated64); + bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2); + options.NumPasses = m_NumPasses; + if (options.NumPasses == 0xFFFFFFFF) + { + if (isDeflate) + options.NumPasses = (level >= 7 ? kNumDeflatePassesX7 : kNumDeflatePassesX1); + else if (isBZip2) + options.NumPasses = (level >= 9 ? kNumBZip2PassesX9 : + (level >= 7 ? kNumBZip2PassesX7 : kNumBZip2PassesX1)); + } + + options.NumFastBytes = m_NumFastBytes; + if (options.NumFastBytes == 0xFFFFFFFF) + { + if (isDeflate) + options.NumFastBytes = (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1); + } return Update(m_Items, updateItems, outStream, - m_ArchiveIsOpen ? &m_Archive : NULL, &m_Method, updateCallback); + m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback); COM_TRY_END } -static const UInt32 kNumPassesNormal = 1; -static const UInt32 kNumPassesMX = 3; - -static const UInt32 kMatchFastLenNormal = 32; -static const UInt32 kMatchFastLenMX = 64; - STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) { InitMethodProperties(); - Byte mainMethod = NFileHeader::NCompressionMethod::kDeflated; for (int i = 0; i < numProperties; i++) { UString name = UString(names[i]); @@ -216,23 +254,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v } else return E_INVALIDARG; - if (level == 0) - { - mainMethod = NFileHeader::NCompressionMethod::kStored; - } - else if (level < 7) - { - InitMethodProperties(); - if (mainMethod == NFileHeader::NCompressionMethod::kStored) - mainMethod = NFileHeader::NCompressionMethod::kDeflated; - } - else - { - m_Method.NumPasses = kNumPassesMX; - m_Method.NumFastBytes = kMatchFastLenMX; - if (mainMethod == NFileHeader::NCompressionMethod::kStored) - mainMethod = NFileHeader::NCompressionMethod::kDeflated; - } + m_Level = (level <= 9) ? (int)level: 9; continue; } else if (name == L"M") @@ -242,13 +264,13 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v UString valueString = value.bstrVal; valueString.MakeUpper(); if (valueString == L"COPY") - mainMethod = NFileHeader::NCompressionMethod::kStored; + m_MainMethod = NFileHeader::NCompressionMethod::kStored; else if (valueString == L"DEFLATE") - mainMethod = NFileHeader::NCompressionMethod::kDeflated; + m_MainMethod = NFileHeader::NCompressionMethod::kDeflated; else if (valueString == L"DEFLATE64") - mainMethod = NFileHeader::NCompressionMethod::kDeflated64; + m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64; else if (valueString == L"BZIP2") - mainMethod = NFileHeader::NCompressionMethod::kBZip2; + m_MainMethod = NFileHeader::NCompressionMethod::kBZip2; else return E_INVALIDARG; } @@ -260,7 +282,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v case NFileHeader::NCompressionMethod::kDeflated: case NFileHeader::NCompressionMethod::kDeflated64: case NFileHeader::NCompressionMethod::kBZip2: - mainMethod = (Byte)value.ulVal; + m_MainMethod = (Byte)value.ulVal; break; default: return E_INVALIDARG; @@ -273,25 +295,21 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v { if (value.vt != VT_UI4) return E_INVALIDARG; - m_Method.NumPasses = value.ulVal; - if (m_Method.NumPasses < 1 || m_Method.NumPasses > 4) + if (value.ulVal < 1 || value.ulVal > 10) return E_INVALIDARG; + m_NumPasses = value.ulVal; } else if (name == L"FB") { if (value.vt != VT_UI4) return E_INVALIDARG; - m_Method.NumFastBytes = value.ulVal; - if (m_Method.NumFastBytes < 3 || m_Method.NumFastBytes > 255) + if (value.ulVal < 3 || value.ulVal > 255) return E_INVALIDARG; + m_NumFastBytes = value.ulVal; } else return E_INVALIDARG; } - m_Method.MethodSequence.Clear(); - if (mainMethod != NFileHeader::NCompressionMethod::kStored) - m_Method.MethodSequence.Add(mainMethod); - m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); return S_OK; } diff --git a/7zip/Archive/makefile b/7zip/Archive/makefile index 3ec954ab..a5858144 100755 --- a/7zip/Archive/makefile +++ b/7zip/Archive/makefile @@ -6,6 +6,7 @@ DIRS = \ Cpio\~ \ Deb\~ \ GZip\~ \ + Lzh\~ \ Rar\~ \ RPM\~ \ Split\~ \ diff --git a/7zip/Bundles/SFXWin/Main.cpp b/7zip/Bundles/SFXWin/Main.cpp index e037e10e..60807a3b 100755 --- a/7zip/Bundles/SFXWin/Main.cpp +++ b/7zip/Bundles/SFXWin/Main.cpp @@ -27,6 +27,7 @@ int APIENTRY WinMain( int nCmdShow) { g_hInstance = (HINSTANCE)hInstance; + UString password; bool assumeYes = false; bool outputFolderDefined = false; UString outputFolder; @@ -43,6 +44,10 @@ int APIENTRY WinMain( NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder); outputFolderDefined = !outputFolder.IsEmpty(); } + else if (s.Left(2).CompareNoCase(L"-p") == 0) + { + password = s.Mid(2); + } } UString path; @@ -58,9 +63,14 @@ int APIENTRY WinMain( COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = !password.IsEmpty(); + openCallback.Password = password; + CExtractCallbackImp *ecs = new CExtractCallbackImp; CMyComPtr extractCallback = ecs; ecs->Init(); + ecs->PasswordIsDefined = !password.IsEmpty(); + ecs->Password = password; CExtractOptions eo; eo.OutputDir = outputFolderDefined ? outputFolder : diff --git a/7zip/Bundles/SFXWin/SFXWin.dsp b/7zip/Bundles/SFXWin/SFXWin.dsp index a6bfbd40..f49239ba 100755 --- a/7zip/Bundles/SFXWin/SFXWin.dsp +++ b/7zip/Bundles/SFXWin/SFXWin.dsp @@ -526,14 +526,6 @@ SOURCE=..\..\FileManager\FormatUtils.cpp SOURCE=..\..\FileManager\FormatUtils.h # End Source File -# Begin Source File - -SOURCE=..\..\FileManager\OpenCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\FileManager\OpenCallback.h -# End Source File # End Group # Begin Group "Windows" diff --git a/7zip/Bundles/SFXWin/makefile b/7zip/Bundles/SFXWin/makefile index 00cefa85..58d56e2c 100755 --- a/7zip/Bundles/SFXWin/makefile +++ b/7zip/Bundles/SFXWin/makefile @@ -74,7 +74,6 @@ UI_COMMON_OBJS = \ FM_OBJS = \ $O\ExtractCallback.obj \ $O\FormatUtils.obj \ - $O\OpenCallback.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ diff --git a/7zip/Compress/Huffman/HuffmanDecoder.h b/7zip/Compress/Huffman/HuffmanDecoder.h index 096181fc..c956869e 100755 --- a/7zip/Compress/Huffman/HuffmanDecoder.h +++ b/7zip/Compress/Huffman/HuffmanDecoder.h @@ -15,12 +15,11 @@ const UInt32 kValueTableBits = 9; template class CDecoder { - UInt32 m_Limitits[kNumBitsInLongestCode + 1]; // m_Limitits[i] = value limit for symbols with length = i + UInt32 m_Limits[kNumBitsInLongestCode + 1]; // m_Limits[i] = value limit for symbols with length = i UInt32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i UInt32 m_Symbols[m_NumSymbols]; // symbols: at first with len = 1 then 2, ... 15. Byte m_Lengths[1 << kValueTableBits]; public: - void SetNumSymbols(UInt32 numSymbols) { m_NumSymbols = numSymbols; } void SetCodeLengths(const Byte *codeLengths); template UInt32 DecodeSymbol(TBitDecoder *bitStream) @@ -29,15 +28,15 @@ public: UInt32 value = bitStream->GetValue(kNumBitsInLongestCode); - if (value < m_Limitits[kValueTableBits]) + if (value < m_Limits[kValueTableBits]) numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)]; else for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++) - if (value < m_Limitits[numBits]) + if (value < m_Limits[numBits]) break; bitStream->MovePos(numBits); UInt32 index = m_Positions[numBits] + - ((value - m_Limitits[numBits - 1]) >> (kNumBitsInLongestCode - numBits)); + ((value - m_Limits[numBits - 1]) >> (kNumBitsInLongestCode - numBits)); if (index >= m_NumSymbols) throw CDecoderException(); // test it return m_Symbols[index]; @@ -60,7 +59,7 @@ void CDecoder::SetCodeLengths(const Byte *c lenCounts[codeLength]++; } lenCounts[0] = 0; - tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0; + tmpPositions[0] = m_Positions[0] = m_Limits[0] = 0; UInt32 startPos = 0; UInt32 index = 0; const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); @@ -69,13 +68,13 @@ void CDecoder::SetCodeLengths(const Byte *c startPos += lenCounts[i] << (kNumBitsInLongestCode - i); if (startPos > kMaxValue) throw CDecoderException(); - m_Limitits[i] = startPos; + m_Limits[i] = startPos; m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; tmpPositions[i] = m_Positions[i]; if(i <= kValueTableBits) { - UInt32 limit = (m_Limitits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it + UInt32 limit = (m_Limits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it memset(m_Lengths + index, Byte(i), limit - index); index = limit; } diff --git a/7zip/Compress/LZ/LZInWindow.cpp b/7zip/Compress/LZ/LZInWindow.cpp index 0c76788f..a16a2c19 100755 --- a/7zip/Compress/LZ/LZInWindow.cpp +++ b/7zip/Compress/LZ/LZInWindow.cpp @@ -22,9 +22,12 @@ bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 kee { Free(); _blockSize = blockSize; - _bufferBase = (Byte *)::BigAlloc(_blockSize); + if (_blockSize != 0) + _bufferBase = (Byte *)::BigAlloc(_blockSize); } _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; + if (_blockSize == 0) + return true; return (_bufferBase != 0); } diff --git a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp index 77a12253..d3965656 100755 --- a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp +++ b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -34,6 +34,8 @@ extern "C" using namespace NCommandLineParser; +static const char *kCantAllocate = "Can not allocate memory"; + namespace NKey { enum Enum { @@ -129,7 +131,7 @@ static bool GetNumber(const wchar_t *s, UInt32 &value) int main2(int n, const char *args[]) { - fprintf(stderr, "\nLZMA 4.23 Copyright (c) 1999-2005 Igor Pavlov 2005-06-29\n"); + fprintf(stderr, "\nLZMA 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); if (n == 1) { @@ -258,9 +260,13 @@ int main2(int n, const char *args[]) if (fileSize > 0xF0000000) throw "File is too big"; UInt32 inSize = (UInt32)fileSize; - Byte *inBuffer = (Byte *)MyAlloc((size_t)inSize); - if (inBuffer == 0) - throw "Can not allocate memory"; + Byte *inBuffer = 0; + if (inSize != 0) + { + inBuffer = (Byte *)MyAlloc((size_t)inSize); + if (inBuffer == 0) + throw kCantAllocate; + } UInt32 processedSize; if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK) @@ -268,15 +274,18 @@ int main2(int n, const char *args[]) if ((UInt32)inSize != processedSize) throw "Read size error"; - Byte *outBuffer; + Byte *outBuffer = 0; size_t outSizeProcessed; if (encodeMode) { // we allocate 105% of original size for output buffer size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16); - outBuffer = (Byte *)MyAlloc((size_t)outSize); - if (outBuffer == 0) - throw "Can not allocate memory"; + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc((size_t)outSize); + if (outBuffer == 0) + throw kCantAllocate; + } if (!dictionaryIsDefined) dictionary = 1 << 23; int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, @@ -292,10 +301,12 @@ int main2(int n, const char *args[]) size_t outSize; if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0) throw "data error"; - outBuffer = (Byte *)MyAlloc(outSize); - if (outBuffer == 0) - throw "Can not allocate memory"; - + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc(outSize); + if (outBuffer == 0) + throw kCantAllocate; + } int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free); if (res != 0) throw "LzmaDecoder error"; diff --git a/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/7zip/Compress/LZMA_Alone/LzmaRam.cpp index bc8a0937..387162b2 100755 --- a/7zip/Compress/LZMA_Alone/LzmaRam.cpp +++ b/7zip/Compress/LZMA_Alone/LzmaRam.cpp @@ -177,10 +177,13 @@ int LzmaRamEncode( bool useFilter = (filterMode != SZ_FILTER_NO); if (useFilter) { - filteredStream = (Byte *)MyAlloc(inSize); - if (filteredStream == 0) - return SZE_OUTOFMEMORY; - memmove(filteredStream, inBuffer, inSize); + if (inSize != 0) + { + filteredStream = (Byte *)MyAlloc(inSize); + if (filteredStream == 0) + return SZE_OUTOFMEMORY; + memmove(filteredStream, inBuffer, inSize); + } UInt32 _prevMask; UInt32 _prevPos; x86_Convert_Init(_prevMask, _prevPos); diff --git a/7zip/Compress/LZMA_C/LzmaStateTest.c b/7zip/Compress/LZMA_C/LzmaStateTest.c index 23f9aa25..5df4e438 100755 --- a/7zip/Compress/LZMA_C/LzmaStateTest.c +++ b/7zip/Compress/LZMA_C/LzmaStateTest.c @@ -3,7 +3,7 @@ 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) +This file is part of LZMA SDK 4.26 (2005-08-02) */ #include @@ -85,11 +85,16 @@ int main3(FILE *inFile, FILE *outFile, char *rs) if (state.Probs == 0) return PrintError(rs, kCantAllocateMessage); - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); - if (state.Dictionary == 0) + if (state.Properties.DictionarySize == 0) + state.Dictionary = 0; + else { - free(state.Probs); - return PrintError(rs, kCantAllocateMessage); + state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); + if (state.Dictionary == 0) + { + free(state.Probs); + return PrintError(rs, kCantAllocateMessage); + } } /* Decompress */ @@ -155,7 +160,7 @@ int main2(int numArgs, const char *args[], char *rs) FILE *outFile = 0; int res; - sprintf(rs + strlen(rs), "\nLZMA Decoder 4.21 Copyright (c) 1999-2005 Igor Pavlov 2005-06-08\n"); + sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); if (numArgs < 2 || numArgs > 3) { sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); diff --git a/7zip/Compress/LZMA_C/LzmaTest.c b/7zip/Compress/LZMA_C/LzmaTest.c index abc5c3c6..b4ca5422 100755 --- a/7zip/Compress/LZMA_C/LzmaTest.c +++ b/7zip/Compress/LZMA_C/LzmaTest.c @@ -3,7 +3,7 @@ LzmaTest.c Test application for LZMA Decoder This file written and distributed to public domain by Igor Pavlov. -This file is part of LZMA SDK 4.22 (2005-06-10) +This file is part of LZMA SDK 4.26 (2005-08-02) */ #include @@ -17,13 +17,21 @@ 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) - { return fread(data, 1, size, file); } +{ + if (size == 0) + return 0; + return fread(data, 1, size, file); +} 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); } +{ + if (size == 0) + return 0; + return fwrite(data, 1, size, file); +} int MyWriteFileAndCheck(FILE *file, const void *data, size_t size) { return (MyWriteFile(file, data, size) == size); } @@ -145,23 +153,32 @@ int main3(FILE *inFile, FILE *outFile, char *rs) state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); #ifdef _LZMA_OUT_READ - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); + if (state.Properties.DictionarySize == 0) + state.Dictionary = 0; + else + state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); #else - outStream = (unsigned char *)malloc(outSizeFull); + if (outSizeFull == 0) + outStream = 0; + else + outStream = (unsigned char *)malloc(outSizeFull); #endif #ifndef _LZMA_IN_CB - inStream = (unsigned char *)malloc(compressedSize); + if (compressedSize == 0) + inStream = 0; + else + inStream = (unsigned char *)malloc(compressedSize); #endif if (state.Probs == 0 #ifdef _LZMA_OUT_READ - || state.Dictionary == 0 + || state.Dictionary == 0 && state.Properties.DictionarySize != 0 #else - || outStream == 0 + || outStream == 0 && outSizeFull != 0 #endif #ifndef _LZMA_IN_CB - || inStream == 0 + || inStream == 0 && compressedSize != 0 #endif ) { @@ -290,7 +307,7 @@ int main2(int numArgs, const char *args[], char *rs) FILE *outFile = 0; int res; - sprintf(rs + strlen(rs), "\nLZMA Decoder 4.21 Copyright (c) 1999-2005 Igor Pavlov 2005-06-08\n"); + sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); if (numArgs < 2 || numArgs > 3) { sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); diff --git a/7zip/Compress/Lzh/LzhDecoder.cpp b/7zip/Compress/Lzh/LzhDecoder.cpp new file mode 100755 index 00000000..e3988a75 --- /dev/null +++ b/7zip/Compress/Lzh/LzhDecoder.cpp @@ -0,0 +1,216 @@ +// LzhDecoder.cpp + +#include "StdAfx.h" + +#include "LzhDecoder.h" + +#include "Windows/Defs.h" + +namespace NCompress{ +namespace NLzh { +namespace NDecoder { + +static const UInt32 kHistorySize = (1 << 16); + +static const int kBlockSizeBits = 16; +static const int kNumCBits = 9; +static const int kNumLevelBits = 5; // smallest integer such that (1 << kNumLevelBits) > kNumLevelSymbols/ + +UInt32 CCoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +HRESULT CCoder::ReadLevelTable() +{ + int n = ReadBits(kNumLevelBits); + if (n == 0) + { + m_LevelHuffman.Symbol = ReadBits(kNumLevelBits); + if (m_LevelHuffman.Symbol >= kNumLevelSymbols) + return S_FALSE; + } + else + { + if (n > kNumLevelSymbols) + return S_FALSE; + m_LevelHuffman.Symbol = -1; + Byte lens[kNumLevelSymbols]; + int i = 0; + while (i < n) + { + int c = m_InBitStream.ReadBits(3); + if (c == 7) + while (ReadBits(1)) + if (c++ > kMaxHuffmanLen) + return S_FALSE; + lens[i++] = (Byte)c; + if (i == kNumSpecLevelSymbols) + { + c = ReadBits(2); + while (--c >= 0) + lens[i++] = 0; + } + } + while (i < kNumLevelSymbols) + lens[i++] = 0; + m_LevelHuffman.SetCodeLengths(lens); + } + return S_OK; +} + +HRESULT CCoder::ReadPTable(int numBits) +{ + int n = ReadBits(numBits); + if (n == 0) + { + m_PHuffmanDecoder.Symbol = ReadBits(numBits); + if (m_PHuffmanDecoder.Symbol >= kNumDistanceSymbols) + return S_FALSE; + } + else + { + if (n > kNumDistanceSymbols) + return S_FALSE; + m_PHuffmanDecoder.Symbol = -1; + Byte lens[kNumDistanceSymbols]; + int i = 0; + while (i < n) + { + int c = m_InBitStream.ReadBits(3); + if (c == 7) + while (ReadBits(1)) + { + if (c > kMaxHuffmanLen) + return S_FALSE; + c++; + } + lens[i++] = (Byte)c; + } + while (i < kNumDistanceSymbols) + lens[i++] = 0; + m_PHuffmanDecoder.SetCodeLengths(lens); + } + return S_OK; +} + +HRESULT CCoder::ReadCTable() +{ + int n = ReadBits(kNumCBits); + if (n == 0) + { + m_CHuffmanDecoder.Symbol = ReadBits(kNumCBits); + if (m_CHuffmanDecoder.Symbol >= kNumCSymbols) + return S_FALSE; + } + else + { + if (n > kNumCSymbols) + return S_FALSE; + m_CHuffmanDecoder.Symbol = -1; + Byte lens[kNumCSymbols]; + int i = 0; + while (i < n) + { + int c = m_LevelHuffman.Decode(&m_InBitStream); + if (c < kNumSpecLevelSymbols) + { + if (c == 0) + c = 1; + else if (c == 1) + c = ReadBits(4) + 3; + else + c = ReadBits(kNumCBits) + 20; + while (--c >= 0) + { + if (i > kNumCSymbols) + return S_FALSE; + lens[i++] = 0; + } + } + else + lens[i++] = c - 2; + } + while (i < kNumCSymbols) + lens[i++] = 0; + m_CHuffmanDecoder.SetCodeLengths(lens); + } + return S_OK; +} + +STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + + int pbit; + if (m_NumDictBits <= 13) + pbit = 4; + else + pbit = 5; + + UInt32 blockSize = 0; + + while(pos < *outSize) + { + // for (i = 0; i < dictSize; i++) dtext[i] = 0x20; + + if (blockSize == 0) + { + if (progress != NULL) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + blockSize = ReadBits(kBlockSizeBits); + ReadLevelTable(); + ReadCTable(); + RINOK(ReadPTable(pbit)); + } + blockSize--; + UInt32 c = m_CHuffmanDecoder.Decode(&m_InBitStream); + if (c < 256) + { + m_OutWindowStream.PutByte((Byte)c); + pos++; + } + else + { + // offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3; + UInt32 len = c - 256 + kMinMatch; + UInt32 distance = m_PHuffmanDecoder.Decode(&m_InBitStream); + if (distance != 0) + distance = (1 << (distance - 1)) + ReadBits(distance - 1); + pos += len; + if (distance >= pos) + throw 1; + m_OutWindowStream.CopyBlock(distance, len); + } + } + coderReleaser.NeedFlush = false; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} diff --git a/7zip/Compress/Lzh/LzhDecoder.h b/7zip/Compress/Lzh/LzhDecoder.h new file mode 100755 index 00000000..11784f29 --- /dev/null +++ b/7zip/Compress/Lzh/LzhDecoder.h @@ -0,0 +1,103 @@ +// LzhDecoder.h + +#ifndef __COMPRESS_LZH_DECODER_H +#define __COMPRESS_LZH_DECODER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../Huffman/HuffmanDecoder.h" +#include "../LZ/LZOutWindow.h" + +namespace NCompress { +namespace NLzh { +namespace NDecoder { + +const int kMaxHuffmanLen = 16; // Check it + +const int kNumSpecLevelSymbols = 3; +const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen; + +const int kDictBitsMax = 16; +const int kNumDistanceSymbols = kDictBitsMax + 1; + +const int kMaxMatch = 256; +const int kMinMatch = 3; +const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch; + +template +class CHuffmanDecoder:public NCompress::NHuffman::CDecoder +{ +public: + int Symbol; + template + UInt32 Decode(TBitDecoder *bitStream) + { + if (Symbol >= 0) + return (UInt32)Symbol; + return DecodeSymbol(bitStream); + } +}; + +class CCoder : + public ICompressCoder, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + NStream::NMSBF::CDecoder m_InBitStream; + + int m_NumDictBits; + + CHuffmanDecoder m_LevelHuffman; + CHuffmanDecoder m_PHuffmanDecoder; + CHuffmanDecoder m_CHuffmanDecoder; + + void CCoder::ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + void MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize); + + UInt32 ReadBits(int numBits); + HRESULT ReadLevelTable(); + HRESULT ReadPTable(int numBits); + HRESULT ReadCTable(); + +public: + + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; } + CCoder(): m_NumDictBits(0) {} +}; + +}}} + +#endif diff --git a/7zip/Compress/PPMD/PPMDSubAlloc.h b/7zip/Compress/PPMD/PPMDSubAlloc.h index 7275d237..5a333fe3 100755 --- a/7zip/Compress/PPMD/PPMDSubAlloc.h +++ b/7zip/Compress/PPMD/PPMDSubAlloc.h @@ -109,8 +109,11 @@ public: if (SubAllocatorSize == size) return true; StopSubAllocator(); - if ((HeapStart = (Byte *)::BigAlloc(size)) == 0) - return false; + if (size == 0) + HeapStart = 0; + else + if ((HeapStart = (Byte *)::BigAlloc(size)) == 0) + return false; SubAllocatorSize = size; return true; } diff --git a/7zip/FileManager/Panel.cpp b/7zip/FileManager/Panel.cpp index b95c6f8b..8a06ac29 100755 --- a/7zip/FileManager/Panel.cpp +++ b/7zip/FileManager/Panel.cpp @@ -472,8 +472,8 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct) // _headerReBar.MaximizeBand(1, false); } - _statusBar.Create(WS_CHILD | WS_VISIBLE, TEXT("Statuys"), (*this), _statusBarID); - // _statusBar2.Create(WS_CHILD | WS_VISIBLE, TEXT("Statuys"), (*this), _statusBarID + 1); + _statusBar.Create(WS_CHILD | WS_VISIBLE, TEXT("Status"), (*this), _statusBarID); + // _statusBar2.Create(WS_CHILD | WS_VISIBLE, TEXT("Status"), (*this), _statusBarID + 1); int sizes[] = {150, 200, 250, -1}; _statusBar.SetParts(4, sizes); diff --git a/7zip/FileManager/Panel.h b/7zip/FileManager/Panel.h index 3a54552c..fc0a9c68 100755 --- a/7zip/FileManager/Panel.h +++ b/7zip/FileManager/Panel.h @@ -185,6 +185,7 @@ private: // void InitColumns2(PROPID sortID); void InsertColumn(int index); + void SetFocusedSelectedItem(int index); void RefreshListCtrl(const UString &focusedName, int focusedPos, const UStringVector &selectedNames); @@ -402,6 +403,10 @@ public: public: CDisableTimerProcessing(CPanel &panel): _panel(panel) { + Disable(); + } + void Disable() + { _processTimerMem = _panel._processTimer; _processNotifyMem = _panel._processNotify; _panel._processTimer = false; diff --git a/7zip/FileManager/PanelItems.cpp b/7zip/FileManager/PanelItems.cpp index 675ef6ee..d400015b 100755 --- a/7zip/FileManager/PanelItems.cpp +++ b/7zip/FileManager/PanelItems.cpp @@ -283,6 +283,18 @@ void CPanel::RefreshListCtrlSaveFocused() RefreshListCtrl(state); } +void CPanel::SetFocusedSelectedItem(int index) +{ + UINT state = LVIS_FOCUSED | LVIS_SELECTED; + _listView.SetItemState(index, state, state); + if (!_mySelectMode) + { + int realIndex = GetRealItemIndex(index); + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = true; + } +} + void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, const UStringVector &selectedNames) { @@ -456,17 +468,13 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, // OutputDebugStringA("End2\n"); if(_listView.GetItemCount() > 0 && cursorIndex >= 0) - { - UINT state = LVIS_FOCUSED | LVIS_SELECTED; - _listView.SetItemState(cursorIndex, state, state); - } + SetFocusedSelectedItem(cursorIndex); _listView.SortItems(CompareItems, (LPARAM)this); if (cursorIndex < 0 && _listView.GetItemCount() > 0) { if (focusedPos >= _listView.GetItemCount()) focusedPos = _listView.GetItemCount() - 1; - UINT state = LVIS_FOCUSED | LVIS_SELECTED; - _listView.SetItemState(focusedPos, state, state); + SetFocusedSelectedItem(focusedPos); } // m_RedrawEnabled = true; _listView.EnsureVisible(_listView.GetFocusedItem(), false); diff --git a/7zip/MyVersion.h b/7zip/MyVersion.h index ceda0fbc..4f3c3cd4 100755 --- a/7zip/MyVersion.h +++ b/7zip/MyVersion.h @@ -1,7 +1,7 @@ #define MY_VER_MAJOR 4 -#define MY_VER_MINOR 25 -#define MY_VERSION "4.25 beta" -#define MY_7ZIP_VERSION "7-Zip 4.25 beta" -#define MY_DATE "2005-07-31" +#define MY_VER_MINOR 26 +#define MY_VERSION "4.26 beta" +#define MY_7ZIP_VERSION "7-Zip 4.26 beta" +#define MY_DATE "2005-08-05" #define MY_COPYRIGHT "Copyright (c) 1999-2005 Igor Pavlov" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/7zip/UI/Common/ArchiveCommandLine.cpp b/7zip/UI/Common/ArchiveCommandLine.cpp index 921fb099..70c2d804 100755 --- a/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/7zip/UI/Common/ArchiveCommandLine.cpp @@ -799,7 +799,11 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) UStringVector archivePaths; int i; for (i = 0; i < dirItems.Size(); i++) - archivePaths.Add(dirItems[i].FullPath); + { + const CDirItem &dirItem = dirItems[i]; + if (!dirItem.IsDirectory()) + archivePaths.Add(dirItem.FullPath); + } if (archivePaths.Size() == 0) throw "there is no such archive"; diff --git a/7zip/UI/Explorer/ContextMenu.cpp b/7zip/UI/Explorer/ContextMenu.cpp index 5d945c60..06465e86 100755 --- a/7zip/UI/Explorer/ContextMenu.cpp +++ b/7zip/UI/Explorer/ContextMenu.cpp @@ -418,19 +418,16 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UString s; FillCommand2(kExtractTo, s, commandMapItem); UString folder; - folder += UString(L"\""); if (_fileNames.Size() == 1) - folder += GetSubFolderNameForExtract(fileInfo.Name); + folder = GetSubFolderNameForExtract(fileInfo.Name); else - folder += L'*'; - folder += L"\\\""; - + folder = L'*'; if (_dropMode) commandMapItem.Folder = _dropPath; else commandMapItem.Folder = folderPrefix; commandMapItem.Folder += folder; - s = MyFormatNew(s, GetReducedString(folder)); + s = MyFormatNew(s, GetReducedString(UString(L"\"") + folder + UString(L"\\\""))); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); _commandMap.Add(commandMapItem); } diff --git a/7zip/UI/Explorer/resource.rc b/7zip/UI/Explorer/resource.rc index fb0f3796..bf7601d9 100755 --- a/7zip/UI/Explorer/resource.rc +++ b/7zip/UI/Explorer/resource.rc @@ -3,7 +3,7 @@ MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip") -1 24 MOVEABLE PURE "7-zip.dll.manifest" +1 24 "7-zip.dll.manifest" STRINGTABLE BEGIN diff --git a/7zip/UI/GUI/ExtractDialog.h b/7zip/UI/GUI/ExtractDialog.h index 94027f4c..34f93f96 100755 --- a/7zip/UI/GUI/ExtractDialog.h +++ b/7zip/UI/GUI/ExtractDialog.h @@ -64,7 +64,9 @@ public: // NExtractionDialog::NFilesMode::EEnum FilesMode; UString DirectoryPath; + #ifndef _SFX UString Password; + #endif NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; diff --git a/7zip/UI/GUI/ExtractGUI.cpp b/7zip/UI/GUI/ExtractGUI.cpp index d7e714cd..de6d1b8a 100755 --- a/7zip/UI/GUI/ExtractGUI.cpp +++ b/7zip/UI/GUI/ExtractGUI.cpp @@ -109,8 +109,10 @@ HRESULT ExtractGUI( outputDir = dialog.DirectoryPath; options.OverwriteMode = dialog.OverwriteMode; options.PathMode = dialog.PathMode; + #ifndef _SFX openCallback->Password = dialog.Password; openCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); + #endif } if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir)) { diff --git a/Common/Alloc.cpp b/Common/Alloc.cpp index 36338370..3ca49d1a 100755 --- a/Common/Alloc.cpp +++ b/Common/Alloc.cpp @@ -20,10 +20,11 @@ int g_allocCountBig = 0; void *MyAlloc(size_t size) throw() { + if (size == 0) + return 0; #ifdef _SZ_ALLOC_DEBUG fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++); #endif - return ::malloc(size); } @@ -39,6 +40,8 @@ void MyFree(void *address) throw() void *BigAlloc(size_t size) throw() { + if (size == 0) + return 0; #ifdef _SZ_ALLOC_DEBUG fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); #endif diff --git a/DOC/Methods.txt b/DOC/Methods.txt index 82ee9d3a..593e911e 100755 --- a/DOC/Methods.txt +++ b/DOC/Methods.txt @@ -59,6 +59,7 @@ List of defined IDs 04 - Arj 01 - Arj (1,2,3) 02 - Arj 4 + 05 - Lzh 07 - Reserved diff --git a/DOC/history.txt b/DOC/history.txt index 81e29ef4..3f340525 100755 --- a/DOC/history.txt +++ b/DOC/history.txt @@ -1,6 +1,11 @@ Sources history of the 7-Zip ---------------------------- + Version 4.26 beta 2005-08-05 + -------------------------------------- + - MyAlloc(0)/BigAlloc(0) now return 0 + + Version 4.25 beta 2005-07-31 -------------------------------------- - More 64-bit compatibilty diff --git a/DOC/lzma.txt b/DOC/lzma.txt index 8e73fa36..b7816774 100755 --- a/DOC/lzma.txt +++ b/DOC/lzma.txt @@ -1,7 +1,7 @@ -LZMA SDK 4.23 +LZMA SDK 4.26 ------------- -LZMA SDK 4.23 Copyright (C) 1999-2005 Igor Pavlov +LZMA SDK 4.26 Copyright (C) 1999-2005 Igor Pavlov LZMA SDK provides developers with documentation, source code, and sample code necessary to write software that uses LZMA compression.