mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 02:07:06 -06:00
4.26 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
af1fe52701
commit
31e7b924e8
@@ -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++;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
72
7zip/Archive/Lzh/DllExports.cpp
Executable file
72
7zip/Archive/Lzh/DllExports.cpp
Executable 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
7
7zip/Archive/Lzh/Lzh.def
Executable file
@@ -0,0 +1,7 @@
|
||||
; Arj.def
|
||||
|
||||
LIBRARY Arj.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetHandlerProperty PRIVATE
|
||||
317
7zip/Archive/Lzh/Lzh.dsp
Executable file
317
7zip/Archive/Lzh/Lzh.dsp
Executable 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
29
7zip/Archive/Lzh/Lzh.dsw
Executable 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
43
7zip/Archive/Lzh/LzhCRC.cpp
Executable 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
27
7zip/Archive/Lzh/LzhCRC.h
Executable 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
458
7zip/Archive/Lzh/LzhHandler.cpp
Executable 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(¤tTotalUnPacked));
|
||||
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,
|
||||
¤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
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
47
7zip/Archive/Lzh/LzhHandler.h
Executable file
47
7zip/Archive/Lzh/LzhHandler.h
Executable 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
19
7zip/Archive/Lzh/LzhHeader.h
Executable 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
169
7zip/Archive/Lzh/LzhIn.cpp
Executable 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
29
7zip/Archive/Lzh/LzhIn.h
Executable 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
165
7zip/Archive/Lzh/LzhItem.h
Executable 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
|
||||
46
7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
Executable file
46
7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
Executable 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;
|
||||
}
|
||||
|
||||
}}
|
||||
39
7zip/Archive/Lzh/LzhOutStreamWithCRC.h
Executable file
39
7zip/Archive/Lzh/LzhOutStreamWithCRC.h
Executable 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
3
7zip/Archive/Lzh/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
7zip/Archive/Lzh/StdAfx.h
Executable file
8
7zip/Archive/Lzh/StdAfx.h
Executable 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
BIN
7zip/Archive/Lzh/lzh.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
63
7zip/Archive/Lzh/makefile
Executable file
63
7zip/Archive/Lzh/makefile
Executable 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
5
7zip/Archive/Lzh/resource.rc
Executable file
@@ -0,0 +1,5 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("Lzh Plugin", "lzh")
|
||||
|
||||
101 ICON "lzh.ico"
|
||||
@@ -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<ICompressSetCoderProperties> 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<ICompressSetCoderProperties> setCoderProperties;
|
||||
RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 1));
|
||||
}
|
||||
|
||||
}
|
||||
CMyComPtr<ISequentialOutStream> outStreamNew;
|
||||
if (_options.PasswordIsDefined)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -58,11 +58,17 @@ private:
|
||||
CObjectVector<CItemEx> 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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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<IArchiveUpdateCallback> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ DIRS = \
|
||||
Cpio\~ \
|
||||
Deb\~ \
|
||||
GZip\~ \
|
||||
Lzh\~ \
|
||||
Rar\~ \
|
||||
RPM\~ \
|
||||
Split\~ \
|
||||
|
||||
Reference in New Issue
Block a user