4.26 beta

This commit is contained in:
Igor Pavlov
2005-08-05 00:00:00 +00:00
committed by Kornel Lesiński
parent af1fe52701
commit 31e7b924e8
56 changed files with 2185 additions and 188 deletions

View File

@@ -14,6 +14,8 @@ int g_allocCountTemp = 0;
void *SzAlloc(size_t size) void *SzAlloc(size_t size)
{ {
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
g_allocCount++; g_allocCount++;
@@ -35,6 +37,8 @@ void SzFree(void *address)
void *SzAllocTemp(size_t size) void *SzAllocTemp(size_t size)
{ {
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
g_allocCountTemp++; g_allocCountTemp++;

View File

@@ -12,6 +12,11 @@ void SzByteBufferInit(CSzByteBuffer *buffer)
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)) int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
{ {
buffer->Capacity = newCapacity; buffer->Capacity = newCapacity;
if (newCapacity == 0)
{
buffer->Items = 0;
return 1;
}
buffer->Items = (Byte *)allocFunc(newCapacity); buffer->Items = (Byte *)allocFunc(newCapacity);
return (buffer->Items != 0); return (buffer->Items != 0);
} }

View File

@@ -114,11 +114,16 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
return SZE_OUTOFMEMORY; return SZE_OUTOFMEMORY;
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); if (state.Properties.DictionarySize == 0)
if (state.Dictionary == 0) state.Dictionary = 0;
else
{ {
allocMain->Free(state.Probs); state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
return SZE_OUTOFMEMORY; if (state.Dictionary == 0)
{
allocMain->Free(state.Probs);
return SZE_OUTOFMEMORY;
}
} }
LzmaDecoderInit(&state); LzmaDecoderInit(&state);
#endif #endif

View File

@@ -45,18 +45,26 @@ SZ_RESULT SzExtract(
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
#ifndef _LZMA_IN_CB #ifndef _LZMA_IN_CB
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); if (packSize != 0)
if (inBuffer == 0) {
return SZE_OUTOFMEMORY; inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
if (inBuffer == 0)
return SZE_OUTOFMEMORY;
}
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize); res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
if (res == SZ_OK && processedSize != (size_t)packSize) if (res == SZ_OK && processedSize != (size_t)packSize)
res = SZE_FAIL; res = SZE_FAIL;
#endif #endif
if (res == SZ_OK) if (res == SZ_OK)
{ {
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
*outBufferSize = (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; size_t outRealSize;
res = SzDecode(db->Database.PackSizes + res = SzDecode(db->Database.PackSizes +
@@ -81,8 +89,6 @@ SZ_RESULT SzExtract(
res = SZE_FAIL; res = SZE_FAIL;
} }
} }
else
res = SZE_OUTOFMEMORY;
} }
#ifndef _LZMA_IN_CB #ifndef _LZMA_IN_CB
allocTemp->Free(inBuffer); allocTemp->Free(inBuffer);

View File

@@ -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)) SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
{ {
UInt32 startPos = 0; UInt32 startPos = 0;
@@ -52,16 +64,14 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
UInt32 i; UInt32 i;
UInt32 folderIndex = 0; UInt32 folderIndex = 0;
UInt32 indexInFolder = 0; UInt32 indexInFolder = 0;
db->FolderStartPackStreamIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32)); RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
RINOM(db->FolderStartPackStreamIndex);
for(i = 0; i < db->Database.NumFolders; i++) for(i = 0; i < db->Database.NumFolders; i++)
{ {
db->FolderStartPackStreamIndex[i] = startPos; db->FolderStartPackStreamIndex[i] = startPos;
startPos += db->Database.Folders[i].NumPackStreams; startPos += db->Database.Folders[i].NumPackStreams;
} }
db->PackStreamStartPositions = (CFileSize *)allocFunc(db->Database.NumPackStreams * sizeof(CFileSize)); RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc));
RINOM(db->PackStreamStartPositions);
for(i = 0; i < db->Database.NumPackStreams; i++) 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]; startPosSize += db->Database.PackSizes[i];
} }
db->FolderStartFileIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32)); RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
RINOM(db->FolderStartFileIndex); RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), allocFunc));
db->FileIndexToFolderIndexMap = (UInt32 *)allocFunc(db->Database.NumFiles * sizeof(UInt32));
RINOM(db->FileIndexToFolderIndexMap);
for (i = 0; i < db->Database.NumFiles; i++) 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 b = 0;
Byte mask = 0; Byte mask = 0;
size_t i; size_t i;
*v = (int *)allocFunc(numItems * sizeof(int)); RINOK(MySzInAlloc((void **)v, numItems * sizeof(int), allocFunc));
RINOM(*v);
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
{ {
if (mask == 0) if (mask == 0)
@@ -400,8 +406,7 @@ SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, int **v, void * (*allo
RINOK(SzReadByte(sd, &allAreDefined)); RINOK(SzReadByte(sd, &allAreDefined));
if (allAreDefined == 0) if (allAreDefined == 0)
return SzReadBoolVector(sd, numItems, v, allocFunc); return SzReadBoolVector(sd, numItems, v, allocFunc);
*v = (int *)allocFunc(numItems * sizeof(int)); RINOK(MySzInAlloc((void **)v, numItems * sizeof(int), allocFunc));
RINOM(*v);
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
(*v)[i] = 1; (*v)[i] = 1;
return SZ_OK; return SZ_OK;
@@ -416,8 +421,7 @@ SZ_RESULT SzReadHashDigests(
{ {
size_t i; size_t i;
RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc)); RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
*digests = (UInt32 *)allocFunc(numItems * sizeof(UInt32)); RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), allocFunc));
RINOM(*digests);
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
if ((*digestsDefined)[i]) if ((*digestsDefined)[i])
{ {
@@ -440,8 +444,8 @@ SZ_RESULT SzReadPackInfo(
RINOK(SzReadNumber32(sd, numPackStreams)); RINOK(SzReadNumber32(sd, numPackStreams));
RINOK(SzWaitAttribute(sd, k7zIdSize)); 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++) for(i = 0; i < *numPackStreams; i++)
{ {
@@ -463,10 +467,8 @@ SZ_RESULT SzReadPackInfo(
} }
if (*packCRCsDefined == 0) if (*packCRCsDefined == 0)
{ {
*packCRCsDefined = (int *)allocFunc((size_t)*numPackStreams * sizeof(int)); RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(int), allocFunc));
RINOM(*packCRCsDefined); RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), allocFunc));
*packCRCs = (UInt32 *)allocFunc((size_t)*numPackStreams * sizeof(UInt32));
RINOM(*packCRCs);
for(i = 0; i < *numPackStreams; i++) for(i = 0; i < *numPackStreams; i++)
{ {
(*packCRCsDefined)[i] = 0; (*packCRCsDefined)[i] = 0;
@@ -494,8 +496,8 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
RINOK(SzReadNumber32(sd, &numCoders)); RINOK(SzReadNumber32(sd, &numCoders));
folder->NumCoders = numCoders; folder->NumCoders = numCoders;
folder->Coders = (CCoderInfo *)allocFunc((size_t)numCoders * sizeof(CCoderInfo)); RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc));
RINOM(folder->Coders);
for (i = 0; i < numCoders; i++) for (i = 0; i < numCoders; i++)
SzCoderInfoInit(folder->Coders + i); SzCoderInfoInit(folder->Coders + i);
@@ -550,9 +552,9 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
numBindPairs = numOutStreams - 1; numBindPairs = numOutStreams - 1;
folder->NumBindPairs = numBindPairs; 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++) for (i = 0; i < numBindPairs; i++)
{ {
CBindPair *bindPair = folder->BindPairs + i;; CBindPair *bindPair = folder->BindPairs + i;;
@@ -563,8 +565,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
numPackedStreams = numInStreams - (UInt32)numBindPairs; numPackedStreams = numInStreams - (UInt32)numBindPairs;
folder->NumPackStreams = numPackedStreams; folder->NumPackStreams = numPackedStreams;
folder->PackStreams = (UInt32 *)allocFunc((size_t)numPackedStreams * sizeof(UInt32)); RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), allocFunc));
RINOM(folder->PackStreams);
if (numPackedStreams == 1) if (numPackedStreams == 1)
{ {
@@ -598,8 +599,9 @@ SZ_RESULT SzReadUnPackInfo(
{ {
RINOK(SzReadSwitch(sd)); 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++) for(i = 0; i < *numFolders; i++)
SzFolderInit((*folders) + i); SzFolderInit((*folders) + i);
@@ -617,8 +619,7 @@ SZ_RESULT SzReadUnPackInfo(
CFolder *folder = (*folders) + i; CFolder *folder = (*folders) + i;
UInt32 numOutStreams = SzFolderGetNumOutStreams(folder); UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
folder->UnPackSizes = (CFileSize *)allocFunc((size_t)numOutStreams * sizeof(CFileSize)); RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc));
RINOM(folder->UnPackSizes);
for(j = 0; j < numOutStreams; j++) for(j = 0; j < numOutStreams; j++)
{ {
@@ -698,14 +699,21 @@ SZ_RESULT SzReadSubStreamsInfo(
RINOK(SzSkeepData(sd)); RINOK(SzSkeepData(sd));
} }
*unPackSizes = (CFileSize *)allocFunc((size_t)*numUnPackStreams * sizeof(CFileSize)); if (*numUnPackStreams == 0)
RINOM(*unPackSizes); {
*unPackSizes = 0;
*digestsDefined = (int *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(int)); *digestsDefined = 0;
RINOM(*digestsDefined); *digests = 0;
}
*digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); else
RINOM(*digests); {
*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++) for(i = 0; i < numFolders; i++)
{ {
@@ -880,8 +888,7 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
len += numAdds; len += numAdds;
} }
file->Name = (char *)allocFunc((size_t)len * sizeof(char)); RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc));
RINOM(file->Name);
len = 0; len = 0;
while(2 <= sd->Size) while(2 <= sd->Size)
@@ -968,8 +975,8 @@ SZ_RESULT SzReadHeader2(
RINOK(SzReadNumber32(sd, &numFiles)); RINOK(SzReadNumber32(sd, &numFiles));
db->Database.NumFiles = numFiles; db->Database.NumFiles = numFiles;
files = (CFileItem *)allocTemp->Alloc((size_t)numFiles * sizeof(CFileItem)); RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocTemp->Alloc));
RINOM(files);
db->Database.Files = files; db->Database.Files = files;
for(i = 0; i < numFiles; i++) for(i = 0; i < numFiles; i++)
SzFileInit(files + i); SzFileInit(files + i);
@@ -1136,9 +1143,8 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
for (i = 0; i < db->NumPackStreams; i++) for (i = 0; i < db->NumPackStreams; i++)
packSize += db->PackSizes[i]; packSize += db->PackSizes[i];
*inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); RINOK(MySzInAlloc((void **)inBuffer, (size_t)packSize, allocTemp->Alloc));
RINOM(*inBuffer);
RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize)); RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
#endif #endif

View File

@@ -1,7 +1,7 @@
/* /*
7zMain.c 7zMain.c
Test application for 7z Decoder 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 <stdio.h> #include <stdio.h>
@@ -71,7 +71,7 @@ int main(int numargs, char *args[])
ISzAlloc allocImp; ISzAlloc allocImp;
ISzAlloc allocTempImp; 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) if (numargs == 1)
{ {
printf( printf(
@@ -146,7 +146,7 @@ int main(int numargs, char *args[])
size_t outSizeProcessed; size_t outSizeProcessed;
CFileItem *f = db.Database.Files + i; CFileItem *f = db.Database.Files + i;
printf(testCommand ? printf(testCommand ?
"Tesing ": "Testing ":
"Extracting"); "Extracting");
printf(" %s", f->Name); printf(" %s", f->Name);
res = SzExtract(&archiveStream.InStream, &db, i, res = SzExtract(&archiveStream.InStream, &db, i,

View File

@@ -152,12 +152,12 @@ HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
if (m_NumReadBytesInBuffer != packSize) if (m_NumReadBytesInBuffer != packSize)
throw "bad block"; throw "bad block";
// Now I don't remember why (checkSum == 0) check is disbaled
// Cab specification: // Cab specification:
// checkSum: May be set to zero if the checksum is not supplied. // checkSum: May be set to zero if the checksum is not supplied.
// but seems it's stupid rule. // but seems it's stupid rule.
if (checkSum == 0) if (checkSum == 0)
dataAreCorrect = true; dataAreCorrect = true;
else
{ {
CCheckSum checkSumCalc; CCheckSum checkSumCalc;
checkSumCalc.Update(m_Buffer, packSize); checkSumCalc.Update(m_Buffer, packSize);

72
7zip/Archive/Lzh/DllExports.cpp Executable file
View File

@@ -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<IInArchive> 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;
}

7
7zip/Archive/Lzh/Lzh.def Executable file
View File

@@ -0,0 +1,7 @@
; Arj.def
LIBRARY Arj.dll
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE

317
7zip/Archive/Lzh/Lzh.dsp Executable file
View File

@@ -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

29
7zip/Archive/Lzh/Lzh.dsw Executable file
View File

@@ -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>
{{{
}}}
###############################################################################

43
7zip/Archive/Lzh/LzhCRC.cpp Executable file
View File

@@ -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;
}
}}

27
7zip/Archive/Lzh/LzhCRC.h Executable file
View File

@@ -0,0 +1,27 @@
// LzhCRC.h
#ifndef __LZH_CRC_H
#define __LZH_CRC_H
#include <stddef.h>
#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

458
7zip/Archive/Lzh/LzhHandler.cpp Executable file
View File

@@ -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<IArchiveOpenCallback> 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<ICompressCoder> lzhDecoder;
CMyComPtr<ICompressCoder> lzh1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder;
CMyComPtr<ICompressCoder> copyCoder;
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked)
{
currentItemUnPacked = 0;
currentItemPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
CMyComPtr<ISequentialOutStream> 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<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream);
realOutStream.Release();
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
UInt64 pos;
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
streamSpec->Init(_stream, itemInfo.PackSize);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalPacked,
&currentTotalUnPacked);
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, &currentItemUnPacked, 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, &currentItemUnPacked, 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
}
}}

47
7zip/Archive/Lzh/LzhHandler.h Executable file
View File

@@ -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<CItemEx> _items;
CMyComPtr<IInStream> _stream;
};
}}
#endif

19
7zip/Archive/Lzh/LzhHeader.h Executable file
View File

@@ -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

169
7zip/Archive/Lzh/LzhIn.cpp Executable file
View File

@@ -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;
}
}}

29
7zip/Archive/Lzh/LzhIn.h Executable file
View File

@@ -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<IInStream> 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

165
7zip/Archive/Lzh/LzhItem.h Executable file
View File

@@ -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<CExtension> 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

View File

@@ -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;
}
}}

View File

@@ -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<ISequentialOutStream> _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

3
7zip/Archive/Lzh/StdAfx.cpp Executable file
View File

@@ -0,0 +1,3 @@
// StdAfx.cpp
#include "StdAfx.h"

8
7zip/Archive/Lzh/StdAfx.h Executable file
View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/MyWindows.h"
#endif

BIN
7zip/Archive/Lzh/lzh.ico Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

63
7zip/Archive/Lzh/makefile Executable file
View File

@@ -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)

5
7zip/Archive/Lzh/resource.rc Executable file
View File

@@ -0,0 +1,5 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_DLL("Lzh Plugin", "lzh")
101 ICON "lzh.ico"

View File

@@ -188,7 +188,8 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream,
{ {
NWindows::NCOM::CPropVariant properties[2] = NWindows::NCOM::CPropVariant properties[2] =
{ {
_options.NumPasses, _options.NumFastBytes _options.NumPasses,
_options.NumFastBytes
}; };
PROPID propIDs[2] = PROPID propIDs[2] =
{ {
@@ -196,10 +197,23 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream,
NCoderPropID::kNumFastBytes NCoderPropID::kNumFastBytes
}; };
CMyComPtr<ICompressSetCoderProperties> setCoderProperties; CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
RINOK(_compressEncoder.QueryInterface( RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
IID_ICompressSetCoderProperties, &setCoderProperties)); RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
setCoderProperties->SetCoderProperties(propIDs, properties, 2); } else if (method == NFileHeader::NCompressionMethod::kBZip2)
{
NWindows::NCOM::CPropVariant properties[1] =
{
_options.NumPasses
};
PROPID propIDs[1] =
{
NCoderPropID::kNumPasses,
};
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 1));
} }
} }
CMyComPtr<ISequentialOutStream> outStreamNew; CMyComPtr<ISequentialOutStream> outStreamNew;
if (_options.PasswordIsDefined) if (_options.PasswordIsDefined)

View File

@@ -153,8 +153,6 @@ CHandler::CHandler():
m_ArchiveIsOpen(false) m_ArchiveIsOpen(false)
{ {
InitMethodProperties(); InitMethodProperties();
m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kDeflated);
m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
} }
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)

View File

@@ -58,11 +58,17 @@ private:
CObjectVector<CItemEx> m_Items; CObjectVector<CItemEx> m_Items;
CInArchive m_Archive; CInArchive m_Archive;
bool m_ArchiveIsOpen; bool m_ArchiveIsOpen;
CCompressionMethodMode m_Method;
int m_Level;
int m_MainMethod;
UInt32 m_NumPasses;
UInt32 m_NumFastBytes;
void InitMethodProperties() void InitMethodProperties()
{ {
m_Method.NumPasses = 1; m_Level = -1;
m_Method.NumFastBytes = 32; m_MainMethod = -1;
m_NumPasses = 0xFFFFFFFF;
m_NumFastBytes = 0xFFFFFFFF;
} }
}; };

View File

@@ -22,6 +22,16 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NZip { 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) STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{ {
*timeType = NFileTimeType::kDOS; *timeType = NFileTimeType::kDOS;
@@ -158,34 +168,62 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback); CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback);
udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
} }
CCompressionMethodMode options;
if (getTextPassword) if (getTextPassword)
{ {
CMyComBSTR password; CMyComBSTR password;
Int32 passwordIsDefined; Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2( RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password)); &passwordIsDefined, &password));
if (m_Method.PasswordIsDefined = IntToBool(passwordIsDefined)) if (options.PasswordIsDefined = IntToBool(passwordIsDefined))
m_Method.Password = UnicodeStringToMultiByte( options.Password = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
(const wchar_t *)password, CP_OEMCP);
} }
else 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, return Update(m_Items, updateItems, outStream,
m_ArchiveIsOpen ? &m_Archive : NULL, &m_Method, updateCallback); m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback);
COM_TRY_END 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) STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{ {
InitMethodProperties(); InitMethodProperties();
Byte mainMethod = NFileHeader::NCompressionMethod::kDeflated;
for (int i = 0; i < numProperties; i++) for (int i = 0; i < numProperties; i++)
{ {
UString name = UString(names[i]); UString name = UString(names[i]);
@@ -216,23 +254,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
} }
else else
return E_INVALIDARG; return E_INVALIDARG;
if (level == 0) m_Level = (level <= 9) ? (int)level: 9;
{
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;
}
continue; continue;
} }
else if (name == L"M") else if (name == L"M")
@@ -242,13 +264,13 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
UString valueString = value.bstrVal; UString valueString = value.bstrVal;
valueString.MakeUpper(); valueString.MakeUpper();
if (valueString == L"COPY") if (valueString == L"COPY")
mainMethod = NFileHeader::NCompressionMethod::kStored; m_MainMethod = NFileHeader::NCompressionMethod::kStored;
else if (valueString == L"DEFLATE") else if (valueString == L"DEFLATE")
mainMethod = NFileHeader::NCompressionMethod::kDeflated; m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
else if (valueString == L"DEFLATE64") else if (valueString == L"DEFLATE64")
mainMethod = NFileHeader::NCompressionMethod::kDeflated64; m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
else if (valueString == L"BZIP2") else if (valueString == L"BZIP2")
mainMethod = NFileHeader::NCompressionMethod::kBZip2; m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
else else
return E_INVALIDARG; return E_INVALIDARG;
} }
@@ -260,7 +282,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
case NFileHeader::NCompressionMethod::kDeflated: case NFileHeader::NCompressionMethod::kDeflated:
case NFileHeader::NCompressionMethod::kDeflated64: case NFileHeader::NCompressionMethod::kDeflated64:
case NFileHeader::NCompressionMethod::kBZip2: case NFileHeader::NCompressionMethod::kBZip2:
mainMethod = (Byte)value.ulVal; m_MainMethod = (Byte)value.ulVal;
break; break;
default: default:
return E_INVALIDARG; return E_INVALIDARG;
@@ -273,25 +295,21 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
{ {
if (value.vt != VT_UI4) if (value.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
m_Method.NumPasses = value.ulVal; if (value.ulVal < 1 || value.ulVal > 10)
if (m_Method.NumPasses < 1 || m_Method.NumPasses > 4)
return E_INVALIDARG; return E_INVALIDARG;
m_NumPasses = value.ulVal;
} }
else if (name == L"FB") else if (name == L"FB")
{ {
if (value.vt != VT_UI4) if (value.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
m_Method.NumFastBytes = value.ulVal; if (value.ulVal < 3 || value.ulVal > 255)
if (m_Method.NumFastBytes < 3 || m_Method.NumFastBytes > 255)
return E_INVALIDARG; return E_INVALIDARG;
m_NumFastBytes = value.ulVal;
} }
else else
return E_INVALIDARG; 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; return S_OK;
} }

View File

@@ -6,6 +6,7 @@ DIRS = \
Cpio\~ \ Cpio\~ \
Deb\~ \ Deb\~ \
GZip\~ \ GZip\~ \
Lzh\~ \
Rar\~ \ Rar\~ \
RPM\~ \ RPM\~ \
Split\~ \ Split\~ \

View File

@@ -27,6 +27,7 @@ int APIENTRY WinMain(
int nCmdShow) int nCmdShow)
{ {
g_hInstance = (HINSTANCE)hInstance; g_hInstance = (HINSTANCE)hInstance;
UString password;
bool assumeYes = false; bool assumeYes = false;
bool outputFolderDefined = false; bool outputFolderDefined = false;
UString outputFolder; UString outputFolder;
@@ -43,6 +44,10 @@ int APIENTRY WinMain(
NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder); NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder);
outputFolderDefined = !outputFolder.IsEmpty(); outputFolderDefined = !outputFolder.IsEmpty();
} }
else if (s.Left(2).CompareNoCase(L"-p") == 0)
{
password = s.Mid(2);
}
} }
UString path; UString path;
@@ -58,9 +63,14 @@ int APIENTRY WinMain(
COpenCallbackGUI openCallback; COpenCallbackGUI openCallback;
openCallback.PasswordIsDefined = !password.IsEmpty();
openCallback.Password = password;
CExtractCallbackImp *ecs = new CExtractCallbackImp; CExtractCallbackImp *ecs = new CExtractCallbackImp;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
ecs->Init(); ecs->Init();
ecs->PasswordIsDefined = !password.IsEmpty();
ecs->Password = password;
CExtractOptions eo; CExtractOptions eo;
eo.OutputDir = outputFolderDefined ? outputFolder : eo.OutputDir = outputFolderDefined ? outputFolder :

View File

@@ -526,14 +526,6 @@ SOURCE=..\..\FileManager\FormatUtils.cpp
SOURCE=..\..\FileManager\FormatUtils.h SOURCE=..\..\FileManager\FormatUtils.h
# End Source File # 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 # End Group
# Begin Group "Windows" # Begin Group "Windows"

View File

@@ -74,7 +74,6 @@ UI_COMMON_OBJS = \
FM_OBJS = \ FM_OBJS = \
$O\ExtractCallback.obj \ $O\ExtractCallback.obj \
$O\FormatUtils.obj \ $O\FormatUtils.obj \
$O\OpenCallback.obj \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \

View File

@@ -15,12 +15,11 @@ const UInt32 kValueTableBits = 9;
template <int kNumBitsInLongestCode, UInt32 m_NumSymbols> template <int kNumBitsInLongestCode, UInt32 m_NumSymbols>
class CDecoder 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_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. UInt32 m_Symbols[m_NumSymbols]; // symbols: at first with len = 1 then 2, ... 15.
Byte m_Lengths[1 << kValueTableBits]; Byte m_Lengths[1 << kValueTableBits];
public: public:
void SetNumSymbols(UInt32 numSymbols) { m_NumSymbols = numSymbols; }
void SetCodeLengths(const Byte *codeLengths); void SetCodeLengths(const Byte *codeLengths);
template <class TBitDecoder> template <class TBitDecoder>
UInt32 DecodeSymbol(TBitDecoder *bitStream) UInt32 DecodeSymbol(TBitDecoder *bitStream)
@@ -29,15 +28,15 @@ public:
UInt32 value = bitStream->GetValue(kNumBitsInLongestCode); UInt32 value = bitStream->GetValue(kNumBitsInLongestCode);
if (value < m_Limitits[kValueTableBits]) if (value < m_Limits[kValueTableBits])
numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)]; numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)];
else else
for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++) for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++)
if (value < m_Limitits[numBits]) if (value < m_Limits[numBits])
break; break;
bitStream->MovePos(numBits); bitStream->MovePos(numBits);
UInt32 index = m_Positions[numBits] + UInt32 index = m_Positions[numBits] +
((value - m_Limitits[numBits - 1]) >> (kNumBitsInLongestCode - numBits)); ((value - m_Limits[numBits - 1]) >> (kNumBitsInLongestCode - numBits));
if (index >= m_NumSymbols) if (index >= m_NumSymbols)
throw CDecoderException(); // test it throw CDecoderException(); // test it
return m_Symbols[index]; return m_Symbols[index];
@@ -60,7 +59,7 @@ void CDecoder<kNumBitsInLongestCode, m_NumSymbols>::SetCodeLengths(const Byte *c
lenCounts[codeLength]++; lenCounts[codeLength]++;
} }
lenCounts[0] = 0; 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 startPos = 0;
UInt32 index = 0; UInt32 index = 0;
const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
@@ -69,13 +68,13 @@ void CDecoder<kNumBitsInLongestCode, m_NumSymbols>::SetCodeLengths(const Byte *c
startPos += lenCounts[i] << (kNumBitsInLongestCode - i); startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
if (startPos > kMaxValue) if (startPos > kMaxValue)
throw CDecoderException(); throw CDecoderException();
m_Limitits[i] = startPos; m_Limits[i] = startPos;
m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1];
tmpPositions[i] = m_Positions[i]; tmpPositions[i] = m_Positions[i];
if(i <= kValueTableBits) 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); memset(m_Lengths + index, Byte(i), limit - index);
index = limit; index = limit;
} }

View File

@@ -22,9 +22,12 @@ bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 kee
{ {
Free(); Free();
_blockSize = blockSize; _blockSize = blockSize;
_bufferBase = (Byte *)::BigAlloc(_blockSize); if (_blockSize != 0)
_bufferBase = (Byte *)::BigAlloc(_blockSize);
} }
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
if (_blockSize == 0)
return true;
return (_bufferBase != 0); return (_bufferBase != 0);
} }

View File

@@ -34,6 +34,8 @@ extern "C"
using namespace NCommandLineParser; using namespace NCommandLineParser;
static const char *kCantAllocate = "Can not allocate memory";
namespace NKey { namespace NKey {
enum Enum enum Enum
{ {
@@ -129,7 +131,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.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) if (n == 1)
{ {
@@ -258,9 +260,13 @@ int main2(int n, const char *args[])
if (fileSize > 0xF0000000) if (fileSize > 0xF0000000)
throw "File is too big"; throw "File is too big";
UInt32 inSize = (UInt32)fileSize; UInt32 inSize = (UInt32)fileSize;
Byte *inBuffer = (Byte *)MyAlloc((size_t)inSize); Byte *inBuffer = 0;
if (inBuffer == 0) if (inSize != 0)
throw "Can not allocate memory"; {
inBuffer = (Byte *)MyAlloc((size_t)inSize);
if (inBuffer == 0)
throw kCantAllocate;
}
UInt32 processedSize; UInt32 processedSize;
if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK) if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK)
@@ -268,15 +274,18 @@ int main2(int n, const char *args[])
if ((UInt32)inSize != processedSize) if ((UInt32)inSize != processedSize)
throw "Read size error"; throw "Read size error";
Byte *outBuffer; Byte *outBuffer = 0;
size_t outSizeProcessed; size_t outSizeProcessed;
if (encodeMode) if (encodeMode)
{ {
// we allocate 105% of original size for output buffer // we allocate 105% of original size for output buffer
size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16); size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
outBuffer = (Byte *)MyAlloc((size_t)outSize); if (outSize != 0)
if (outBuffer == 0) {
throw "Can not allocate memory"; outBuffer = (Byte *)MyAlloc((size_t)outSize);
if (outBuffer == 0)
throw kCantAllocate;
}
if (!dictionaryIsDefined) if (!dictionaryIsDefined)
dictionary = 1 << 23; dictionary = 1 << 23;
int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed,
@@ -292,10 +301,12 @@ int main2(int n, const char *args[])
size_t outSize; size_t outSize;
if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0) if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
throw "data error"; throw "data error";
outBuffer = (Byte *)MyAlloc(outSize); if (outSize != 0)
if (outBuffer == 0) {
throw "Can not allocate memory"; outBuffer = (Byte *)MyAlloc(outSize);
if (outBuffer == 0)
throw kCantAllocate;
}
int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free); int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
if (res != 0) if (res != 0)
throw "LzmaDecoder error"; throw "LzmaDecoder error";

View File

@@ -177,10 +177,13 @@ int LzmaRamEncode(
bool useFilter = (filterMode != SZ_FILTER_NO); bool useFilter = (filterMode != SZ_FILTER_NO);
if (useFilter) if (useFilter)
{ {
filteredStream = (Byte *)MyAlloc(inSize); if (inSize != 0)
if (filteredStream == 0) {
return SZE_OUTOFMEMORY; filteredStream = (Byte *)MyAlloc(inSize);
memmove(filteredStream, inBuffer, inSize); if (filteredStream == 0)
return SZE_OUTOFMEMORY;
memmove(filteredStream, inBuffer, inSize);
}
UInt32 _prevMask; UInt32 _prevMask;
UInt32 _prevPos; UInt32 _prevPos;
x86_Convert_Init(_prevMask, _prevPos); x86_Convert_Init(_prevMask, _prevPos);

View File

@@ -3,7 +3,7 @@ LzmaStateTest.c
Test application for LZMA Decoder (State version) Test application for LZMA Decoder (State version)
This file written and distributed to public domain by Igor Pavlov. 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 <stdio.h> #include <stdio.h>
@@ -85,11 +85,16 @@ int main3(FILE *inFile, FILE *outFile, char *rs)
if (state.Probs == 0) if (state.Probs == 0)
return PrintError(rs, kCantAllocateMessage); return PrintError(rs, kCantAllocateMessage);
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); if (state.Properties.DictionarySize == 0)
if (state.Dictionary == 0) state.Dictionary = 0;
else
{ {
free(state.Probs); state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
return PrintError(rs, kCantAllocateMessage); if (state.Dictionary == 0)
{
free(state.Probs);
return PrintError(rs, kCantAllocateMessage);
}
} }
/* Decompress */ /* Decompress */
@@ -155,7 +160,7 @@ int main2(int numArgs, const char *args[], char *rs)
FILE *outFile = 0; FILE *outFile = 0;
int res; 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) if (numArgs < 2 || numArgs > 3)
{ {
sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");

View File

@@ -3,7 +3,7 @@ LzmaTest.c
Test application for LZMA Decoder Test application for LZMA Decoder
This file written and distributed to public domain by Igor Pavlov. 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 <stdio.h> #include <stdio.h>
@@ -17,13 +17,21 @@ const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory"; 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); } {
if (size == 0)
return 0;
return fread(data, 1, size, file);
}
int MyReadFileAndCheck(FILE *file, void *data, size_t size) int MyReadFileAndCheck(FILE *file, void *data, size_t size)
{ return (MyReadFile(file, data, size) == size);} { return (MyReadFile(file, data, size) == size);}
size_t MyWriteFile(FILE *file, const void *data, size_t 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) int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
{ return (MyWriteFile(file, data, size) == 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)); state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
#ifdef _LZMA_OUT_READ #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 #else
outStream = (unsigned char *)malloc(outSizeFull); if (outSizeFull == 0)
outStream = 0;
else
outStream = (unsigned char *)malloc(outSizeFull);
#endif #endif
#ifndef _LZMA_IN_CB #ifndef _LZMA_IN_CB
inStream = (unsigned char *)malloc(compressedSize); if (compressedSize == 0)
inStream = 0;
else
inStream = (unsigned char *)malloc(compressedSize);
#endif #endif
if (state.Probs == 0 if (state.Probs == 0
#ifdef _LZMA_OUT_READ #ifdef _LZMA_OUT_READ
|| state.Dictionary == 0 || state.Dictionary == 0 && state.Properties.DictionarySize != 0
#else #else
|| outStream == 0 || outStream == 0 && outSizeFull != 0
#endif #endif
#ifndef _LZMA_IN_CB #ifndef _LZMA_IN_CB
|| inStream == 0 || inStream == 0 && compressedSize != 0
#endif #endif
) )
{ {
@@ -290,7 +307,7 @@ int main2(int numArgs, const char *args[], char *rs)
FILE *outFile = 0; FILE *outFile = 0;
int res; 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) if (numArgs < 2 || numArgs > 3)
{ {
sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");

216
7zip/Compress/Lzh/LzhDecoder.cpp Executable file
View File

@@ -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; }
}
}}}

103
7zip/Compress/Lzh/LzhDecoder.h Executable file
View File

@@ -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 <UInt32 m_NumSymbols>
class CHuffmanDecoder:public NCompress::NHuffman::CDecoder<kMaxHuffmanLen, m_NumSymbols>
{
public:
int Symbol;
template <class TBitDecoder>
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<CInBuffer> m_InBitStream;
int m_NumDictBits;
CHuffmanDecoder<kNumLevelSymbols> m_LevelHuffman;
CHuffmanDecoder<kNumDistanceSymbols> m_PHuffmanDecoder;
CHuffmanDecoder<kNumCSymbols> 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

View File

@@ -109,8 +109,11 @@ public:
if (SubAllocatorSize == size) if (SubAllocatorSize == size)
return true; return true;
StopSubAllocator(); StopSubAllocator();
if ((HeapStart = (Byte *)::BigAlloc(size)) == 0) if (size == 0)
return false; HeapStart = 0;
else
if ((HeapStart = (Byte *)::BigAlloc(size)) == 0)
return false;
SubAllocatorSize = size; SubAllocatorSize = size;
return true; return true;
} }

View File

@@ -472,8 +472,8 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct)
// _headerReBar.MaximizeBand(1, false); // _headerReBar.MaximizeBand(1, false);
} }
_statusBar.Create(WS_CHILD | WS_VISIBLE, TEXT("Statuys"), (*this), _statusBarID); _statusBar.Create(WS_CHILD | WS_VISIBLE, TEXT("Status"), (*this), _statusBarID);
// _statusBar2.Create(WS_CHILD | WS_VISIBLE, TEXT("Statuys"), (*this), _statusBarID + 1); // _statusBar2.Create(WS_CHILD | WS_VISIBLE, TEXT("Status"), (*this), _statusBarID + 1);
int sizes[] = {150, 200, 250, -1}; int sizes[] = {150, 200, 250, -1};
_statusBar.SetParts(4, sizes); _statusBar.SetParts(4, sizes);

View File

@@ -185,6 +185,7 @@ private:
// void InitColumns2(PROPID sortID); // void InitColumns2(PROPID sortID);
void InsertColumn(int index); void InsertColumn(int index);
void SetFocusedSelectedItem(int index);
void RefreshListCtrl(const UString &focusedName, int focusedPos, void RefreshListCtrl(const UString &focusedName, int focusedPos,
const UStringVector &selectedNames); const UStringVector &selectedNames);
@@ -402,6 +403,10 @@ public:
public: public:
CDisableTimerProcessing(CPanel &panel): _panel(panel) CDisableTimerProcessing(CPanel &panel): _panel(panel)
{ {
Disable();
}
void Disable()
{
_processTimerMem = _panel._processTimer; _processTimerMem = _panel._processTimer;
_processNotifyMem = _panel._processNotify; _processNotifyMem = _panel._processNotify;
_panel._processTimer = false; _panel._processTimer = false;

View File

@@ -283,6 +283,18 @@ void CPanel::RefreshListCtrlSaveFocused()
RefreshListCtrl(state); 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, void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
const UStringVector &selectedNames) const UStringVector &selectedNames)
{ {
@@ -456,17 +468,13 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
// OutputDebugStringA("End2\n"); // OutputDebugStringA("End2\n");
if(_listView.GetItemCount() > 0 && cursorIndex >= 0) if(_listView.GetItemCount() > 0 && cursorIndex >= 0)
{ SetFocusedSelectedItem(cursorIndex);
UINT state = LVIS_FOCUSED | LVIS_SELECTED;
_listView.SetItemState(cursorIndex, state, state);
}
_listView.SortItems(CompareItems, (LPARAM)this); _listView.SortItems(CompareItems, (LPARAM)this);
if (cursorIndex < 0 && _listView.GetItemCount() > 0) if (cursorIndex < 0 && _listView.GetItemCount() > 0)
{ {
if (focusedPos >= _listView.GetItemCount()) if (focusedPos >= _listView.GetItemCount())
focusedPos = _listView.GetItemCount() - 1; focusedPos = _listView.GetItemCount() - 1;
UINT state = LVIS_FOCUSED | LVIS_SELECTED; SetFocusedSelectedItem(focusedPos);
_listView.SetItemState(focusedPos, state, state);
} }
// m_RedrawEnabled = true; // m_RedrawEnabled = true;
_listView.EnsureVisible(_listView.GetFocusedItem(), false); _listView.EnsureVisible(_listView.GetFocusedItem(), false);

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 4 #define MY_VER_MAJOR 4
#define MY_VER_MINOR 25 #define MY_VER_MINOR 26
#define MY_VERSION "4.25 beta" #define MY_VERSION "4.26 beta"
#define MY_7ZIP_VERSION "7-Zip 4.25 beta" #define MY_7ZIP_VERSION "7-Zip 4.26 beta"
#define MY_DATE "2005-07-31" #define MY_DATE "2005-08-05"
#define MY_COPYRIGHT "Copyright (c) 1999-2005 Igor Pavlov" #define MY_COPYRIGHT "Copyright (c) 1999-2005 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE

View File

@@ -799,7 +799,11 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
UStringVector archivePaths; UStringVector archivePaths;
int i; int i;
for (i = 0; i < dirItems.Size(); 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) if (archivePaths.Size() == 0)
throw "there is no such archive"; throw "there is no such archive";

View File

@@ -418,19 +418,16 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UString s; UString s;
FillCommand2(kExtractTo, s, commandMapItem); FillCommand2(kExtractTo, s, commandMapItem);
UString folder; UString folder;
folder += UString(L"\"");
if (_fileNames.Size() == 1) if (_fileNames.Size() == 1)
folder += GetSubFolderNameForExtract(fileInfo.Name); folder = GetSubFolderNameForExtract(fileInfo.Name);
else else
folder += L'*'; folder = L'*';
folder += L"\\\"";
if (_dropMode) if (_dropMode)
commandMapItem.Folder = _dropPath; commandMapItem.Folder = _dropPath;
else else
commandMapItem.Folder = folderPrefix; commandMapItem.Folder = folderPrefix;
commandMapItem.Folder += folder; commandMapItem.Folder += folder;
s = MyFormatNew(s, GetReducedString(folder)); s = MyFormatNew(s, GetReducedString(UString(L"\"") + folder + UString(L"\\\"")));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
_commandMap.Add(commandMapItem); _commandMap.Add(commandMapItem);
} }

View File

@@ -3,7 +3,7 @@
MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip") 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 STRINGTABLE
BEGIN BEGIN

View File

@@ -64,7 +64,9 @@ public:
// NExtractionDialog::NFilesMode::EEnum FilesMode; // NExtractionDialog::NFilesMode::EEnum FilesMode;
UString DirectoryPath; UString DirectoryPath;
#ifndef _SFX
UString Password; UString Password;
#endif
NExtract::NPathMode::EEnum PathMode; NExtract::NPathMode::EEnum PathMode;
NExtract::NOverwriteMode::EEnum OverwriteMode; NExtract::NOverwriteMode::EEnum OverwriteMode;

View File

@@ -109,8 +109,10 @@ HRESULT ExtractGUI(
outputDir = dialog.DirectoryPath; outputDir = dialog.DirectoryPath;
options.OverwriteMode = dialog.OverwriteMode; options.OverwriteMode = dialog.OverwriteMode;
options.PathMode = dialog.PathMode; options.PathMode = dialog.PathMode;
#ifndef _SFX
openCallback->Password = dialog.Password; openCallback->Password = dialog.Password;
openCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); openCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
#endif
} }
if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir)) if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir))
{ {

View File

@@ -20,10 +20,11 @@ int g_allocCountBig = 0;
void *MyAlloc(size_t size) throw() void *MyAlloc(size_t size) throw()
{ {
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++); fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
#endif #endif
return ::malloc(size); return ::malloc(size);
} }
@@ -39,6 +40,8 @@ void MyFree(void *address) throw()
void *BigAlloc(size_t size) throw() void *BigAlloc(size_t size) throw()
{ {
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
#endif #endif

View File

@@ -59,6 +59,7 @@ List of defined IDs
04 - Arj 04 - Arj
01 - Arj (1,2,3) 01 - Arj (1,2,3)
02 - Arj 4 02 - Arj 4
05 - Lzh
07 - Reserved 07 - Reserved

View File

@@ -1,6 +1,11 @@
Sources history of the 7-Zip 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 Version 4.25 beta 2005-07-31
-------------------------------------- --------------------------------------
- More 64-bit compatibilty - More 64-bit compatibilty

View File

@@ -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, 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.