This commit is contained in:
Igor Pavlov
2003-12-11 00:00:00 +00:00
committed by Kornel Lesiński
commit 8c1b5c7b7e
982 changed files with 118799 additions and 0 deletions

160
7zip/Archive/Rar/DllExports.cpp Executable file
View File

@@ -0,0 +1,160 @@
// DLLExports.cpp
#include "StdAfx.h"
#include <initguid.h>
#include "Common/ComTry.h"
#include "Windows/PropVariant.h"
#include "../../ICoder.h"
#include "../../IPassword.h"
#include "../Common/CodecsPath.h"
// {23170F69-40C1-278B-0601-010000000000}
DEFINE_GUID(CLSID_CCrypto_AES128_Decoder,
0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
#include "RarHandler.h"
HINSTANCE g_hInstance;
/*
static bool GetBaseFolderPrefix(TCHAR *path)
{
TCHAR fullPath[MAX_PATH + 1];
if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0)
return false;
// fullPath = "7-zip\Format\Rar.dll"
LPTSTR fileNamePointer;
TCHAR p[MAX_PATH + 1];
DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1,
p, &fileNamePointer);
if (needLength == 0 || needLength >= MAX_PATH)
return false;
*fileNamePointer = 0;
// p = "7-zip\Format\"
int len = lstrlen(p);
if (len == 0)
return false;
if (p[len - 1] != '\\')
return false;
p[len - 1] = 0;
// p = "7-zip\Format"
needLength = ::GetFullPathName(p, MAX_PATH + 1,
path, &fileNamePointer);
if (needLength == 0 || needLength >= MAX_PATH)
return false;
// fileNamePointer -> "7-zip\"+
*fileNamePointer = 0;
return true;
}
bool GetCompressFolderPrefix(TCHAR *path)
{
if (!GetBaseFolderPrefix(path))
return false;
lstrcat(path, TEXT("Codecs\\"));
return true;
}
*/
void GetCryptoFolderPrefix(TCHAR *path)
{
CSysString s = GetCodecsFolderPrefix();
lstrcpy(path, s);
}
// {23170F69-40C1-278B-0403-010000000000}
DEFINE_GUID(CLSID_CCompressRar15Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
// {23170F69-40C1-278B-0403-020000000000}
DEFINE_GUID(CLSID_CCompressRar20Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
// {23170F69-40C1-278B-0403-030000000000}
DEFINE_GUID(CLSID_CCompressRar29Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00);
/*
// {23170F69-40C1-278B-06F1-0302000000000}
DEFINE_GUID(CLSID_CCryptoRar20Decoder,
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00);
// {23170F69-40C1-278B-06F1-0303000000000}
DEFINE_GUID(CLSID_CCryptoRar29Decoder,
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00);
*/
// {23170F69-40C1-278A-1000-000110020000}
DEFINE_GUID(CLSID_CRarHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
g_hInstance = hInstance;
return TRUE;
}
STDAPI CreateObject(
const GUID *classID,
const GUID *interfaceID,
void **outObject)
{
COM_TRY_BEGIN
*outObject = 0;
if (*classID != CLSID_CRarHandler)
return CLASS_E_CLASSNOTAVAILABLE;
int needIn = *interfaceID == IID_IInArchive;
if (needIn)
{
NArchive::NRar::CHandler *temp = new NArchive::NRar::CHandler;
if (needIn)
{
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
*outObject = inArchive.Detach();
}
else
{
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
*outObject = outArchive.Detach();
}
}
else
return E_NOINTERFACE;
COM_TRY_END
return S_OK;
}
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant propVariant;
switch(propID)
{
case NArchive::kName:
propVariant = L"Rar";
break;
case NArchive::kClassID:
{
if ((value->bstrVal = ::SysAllocStringByteLen(
(const char *)&CLSID_CRarHandler, sizeof(GUID))) != 0)
value->vt = VT_BSTR;
return S_OK;
}
case NArchive::kExtension:
propVariant = L"rar";
break;
case NArchive::kUpdate:
propVariant = false;
break;
case NArchive::kKeepName:
propVariant = false;
break;
}
propVariant.Detach(value);
return S_OK;
}

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

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

433
7zip/Archive/Rar/Rar.dsp Executable file
View File

@@ -0,0 +1,433 @@
# Microsoft Developer Studio Project File - Name="Rar" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Rar - 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 "Rar.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 "Rar.mak" CFG="Rar - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Rar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Rar - 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)" == "Rar - 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 "RAR_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR_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\rar.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Rar - 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 "RAR_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 "RAR_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\rar.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "Rar - Win32 Release"
# Name "Rar - Win32 Debug"
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\DllExports.cpp
# End Source File
# Begin Source File
SOURCE=.\Rar.def
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\resource.rc
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"StdAfx.h"
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\..\SDK\Common\Buffer.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\CRC.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\CRC.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\SDK\Common\DynamicBuffer.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\Types.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 "Archive Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\Common\CodecsPath.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CodecsPath.h
# End Source File
# Begin Source File
SOURCE=..\Common\CoderLoader.h
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer.h
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2.h
# End Source File
# Begin Source File
SOURCE=..\Common\CrossThreadProgress.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CrossThreadProgress.h
# End Source File
# Begin Source File
SOURCE=..\Common\IArchiveHandler.h
# End Source File
# Begin Source File
SOURCE=..\Common\InStreamWithCRC.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\InStreamWithCRC.h
# End Source File
# Begin Source File
SOURCE=..\Common\OutStreamWithCRC.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\OutStreamWithCRC.h
# End Source File
# End Group
# Begin Group "Windows"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Windows\DLL.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\DLL.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileFind.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileFind.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Handle.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Thread.h
# End Source File
# End Group
# Begin Group "Compress"
# 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 "Engine"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\RarHandler.cpp
# End Source File
# Begin Source File
SOURCE=.\RarHandler.h
# End Source File
# Begin Source File
SOURCE=.\RarHeader.cpp
# End Source File
# Begin Source File
SOURCE=.\RarHeader.h
# End Source File
# Begin Source File
SOURCE=.\RarIn.cpp
# End Source File
# Begin Source File
SOURCE=.\RarIn.h
# End Source File
# Begin Source File
SOURCE=.\RarItem.cpp
# End Source File
# Begin Source File
SOURCE=.\RarItem.h
# End Source File
# Begin Source File
SOURCE=.\RarVolumeInStream.cpp
# End Source File
# Begin Source File
SOURCE=.\RarVolumeInStream.h
# End Source File
# End Group
# Begin Group "Crypto"
# PROP Default_Filter ""
# Begin Group "Rar29"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Crypto\RarAES\RarAES.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\RarAES\RarAES.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\RarAES\sha1.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\RarAES\sha1.h
# End Source File
# End Group
# Begin Group "Rar20"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Crypto\Rar20\Rar20Cipher.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Rar20\Rar20Cipher.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Rar20\Rar20Crypto.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Rar20\Rar20Crypto.h
# End Source File
# End Group
# End Group
# Begin Group "7-zip Common"
# PROP Default_Filter ""
# 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\ProgressUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamBinder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamBinder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamObjects.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamObjects.h
# End Source File
# End Group
# Begin Group "7z"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\7z\7zMethods.cpp
# End Source File
# Begin Source File
SOURCE=..\7z\7zMethods.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\Rar.ico
# End Source File
# End Target
# End Project

29
7zip/Archive/Rar/Rar.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: "Rar"=.\Rar.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

977
7zip/Archive/Rar/RarHandler.cpp Executable file
View File

@@ -0,0 +1,977 @@
// RarHandler.cpp
#include "StdAfx.h"
#include "RarHandler.h"
#include "Common/StringConvert.h"
#include "Common/ComTry.h"
#include "../../Common/StreamObjects.h"
// #include "Interface/EnumStatProp.h"
#include "../../Common//ProgressUtils.h"
#include "../../IPassword.h"
#include "Windows/PropVariant.h"
#include "Windows/Time.h"
#include "../../Compress/Copy/CopyCoder.h"
#include "../Common/OutStreamWithCRC.h"
#include "../Common/CoderMixer.h"
#include "../Common/CoderLoader.h"
#include "../Common/CodecsPath.h"
#include "../7z/7zMethods.h"
// #include "../../../Compress/Interface/CompressInterface.h"
// #include "../../../Crypto/Cipher/Common/CipherInterface.h"
#include "../../Crypto/Rar20/Rar20Cipher.h"
#include "../../Crypto/RarAES/RarAES.h"
using namespace NWindows;
using namespace NTime;
// {23170F69-40C1-278B-0403-010000000000}
DEFINE_GUID(CLSID_CCompressRar15Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
// {23170F69-40C1-278B-0403-020000000000}
DEFINE_GUID(CLSID_CCompressRar20Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
// {23170F69-40C1-278B-0403-030000000000}
DEFINE_GUID(CLSID_CCompressRar29Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00);
namespace NArchive {
namespace NRar {
static const wchar_t *kHostOS[] =
{
L"MS DOS",
L"OS/2",
L"Win32",
L"Unix",
L"Mac OS",
L"BeOS"
};
static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown";
enum // PropID
{
kpidUnPackVersion = kpidUserDefined
};
STATPROPSTG kProperties[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME},
{ NULL, kpidCreationTime, VT_FILETIME},
{ NULL, kpidLastAccessTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL},
{ NULL, kpidSolid, VT_BOOL},
{ NULL, kpidCommented, VT_BOOL},
{ NULL, kpidSplitBefore, VT_BOOL},
{ NULL, kpidSplitAfter, VT_BOOL},
{ NULL, kpidCRC, VT_UI4},
{ NULL, kpidHostOS, VT_BSTR},
{ NULL, kpidMethod, VT_BSTR}
// { NULL, kpidDictionarySize, VT_UI4},
// { L"UnPack Version", kpidUnPackVersion, VT_UI1}
};
STATPROPSTG kArchiveProperties[] =
{
{ NULL, kpidSolid, VT_BOOL},
{ NULL, kpidCommented, VT_BOOL},
};
UINT64 CHandler::GetPackSize(int refIndex) const
{
const CRefItem &refItem = _refItems[refIndex];
UINT64 totalPackSize = 0;
for (int i = 0; i < refItem.NumItems; i++)
totalPackSize += _items[refItem.ItemIndex + i].PackSize;
return totalPackSize;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
switch(propID)
{
case kpidSolid:
propVariant = _archiveInfo.IsSolid();
break;
case kpidCommented:
propVariant = _archiveInfo.IsCommented();
break;
}
propVariant.Detach(value);
return S_OK;
COM_TRY_END
}
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 = sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]);
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
if(index >= sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]))
return E_INVALIDARG;
const STATPROPSTG &srcItem = kArchiveProperties[index];
*propID = srcItem.propid;
*varType = srcItem.vt;
*name = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
{
*numItems = _refItems.Size();
return S_OK;
}
static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result)
{
if (!DosTimeToFileTime(rarTime.DosTime, result))
return false;
UINT64 &value = *(UINT64 *)&result;
value += (int)rarTime.LowSecond * 10000000;
UINT64 subTime = ((UINT64)rarTime.SubTime[2] << 16) +
((UINT64)rarTime.SubTime[1] << 8) +
((UINT64)rarTime.SubTime[0]);
// value += (subTime * 10000000) >> 24;
value += subTime;
return true;
}
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
const CRefItem &refItem = _refItems[index];
const CItemEx &item = _items[refItem.ItemIndex];
switch(propID)
{
case kpidPath:
if (item.HasUnicodeName())
propVariant = item.UnicodeName;
else
propVariant = (const wchar_t *)MultiByteToUnicodeString(item.Name, CP_OEMCP);
break;
case kpidIsFolder:
propVariant = item.IsDirectory();
break;
case kpidSize:
propVariant = item.UnPackSize;
break;
case kpidPackedSize:
{
propVariant = GetPackSize(index);
break;
}
case kpidLastWriteTime:
{
FILETIME localFileTime, utcFileTime;
if (RarTimeToFileTime(item.LastWriteTime, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
propVariant = utcFileTime;
break;
}
case kpidCreationTime:
{
if (item.IsCreationTimeDefined)
{
FILETIME localFileTime, utcFileTime;
if (RarTimeToFileTime(item.CreationTime, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
propVariant = utcFileTime;
}
break;
}
case kpidLastAccessTime:
{
if (item.IsLastAccessTimeDefined)
{
FILETIME localFileTime, utcFileTime;
if (RarTimeToFileTime(item.LastAccessTime, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
propVariant = utcFileTime;
}
break;
}
case kpidAttributes:
propVariant = item.GetWinAttributes();
break;
case kpidEncrypted:
propVariant = item.IsEncrypted();
break;
case kpidSolid:
propVariant = IsSolid(index);
break;
case kpidCommented:
propVariant = item.IsCommented();
break;
case kpidSplitBefore:
propVariant = item.IsSplitBefore();
break;
case kpidSplitAfter:
propVariant = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter();
break;
/*
case kpidDictionarySize:
if (!item.IsDirectory())
propVariant = UINT32(0x10000 << item.GetDictSize());
break;
*/
case kpidCRC:
{
const CItemEx &lastItem =
_items[refItem.ItemIndex + refItem.NumItems - 1];
if (lastItem.IsSplitAfter())
propVariant = item.FileCRC;
else
propVariant = lastItem.FileCRC;
break;
}
case kpidUnPackVersion:
propVariant = item.UnPackVersion;
break;
case kpidMethod:
{
UString method;
if (item.Method >= BYTE('0') && item.Method <= BYTE('5'))
{
method = L"m";
wchar_t temp[32];
_itow (item.Method - BYTE('0'), temp, 10);
method += temp;
if (!item.IsDirectory())
{
method += L":";
_itow (16 + item.GetDictSize(), temp, 10);
method += temp;
}
}
else
{
wchar_t temp[32];
_itow (item.Method, temp, 10);
method += temp;
}
propVariant = method;
break;
}
case kpidHostOS:
propVariant = (item.HostOS < kNumHostOSes) ?
(kHostOS[item.HostOS]) : kUnknownOS;
break;
}
propVariant.Detach(value);
return S_OK;
COM_TRY_END
}
class CVolumeName
{
bool _first;
bool _newStyle;
UString _unchangedPart;
UString _changedPart;
UString _afterPart;
public:
CVolumeName(): _newStyle(true) {};
bool InitName(const UString &name, bool newStyle)
{
_first = true;
_newStyle = newStyle;
int dotPos = name.ReverseFind('.');
UString basePart = name;
if (dotPos >= 0)
{
UString ext = name.Mid(dotPos + 1);
if (ext.CompareNoCase(L"RAR")==0 ||
ext.CompareNoCase(L"EXE") == 0)
{
_afterPart = L".rar";
basePart = name.Left(dotPos);
}
}
if (!_newStyle)
{
_afterPart.Empty();
_unchangedPart = basePart + UString(L".");
_changedPart = L"r00";
return true;;
}
int numLetters = 1;
bool splitStyle = false;
if (basePart.Right(numLetters) == L"1")
{
while (numLetters < basePart.Length())
{
if (basePart[basePart.Length() - numLetters - 1] != '0')
break;
numLetters++;
}
}
else
return false;
_unchangedPart = basePart.Left(basePart.Length() - numLetters);
_changedPart = basePart.Right(numLetters);
return true;
}
UString GetNextName()
{
UString newName;
if (_newStyle || !_first)
{
int i;
int numLetters = _changedPart.Length();
for (i = numLetters - 1; i >= 0; i--)
{
wchar_t c = _changedPart[i];
if (c == L'9')
{
c = L'0';
newName = c + newName;
if (i == 0)
newName = UString(L'1') + newName;
continue;
}
c++;
newName = UString(c) + newName;
i--;
for (; i >= 0; i--)
newName = _changedPart[i] + newName;
break;
}
_changedPart = newName;
}
_first = false;
return _unchangedPart + _changedPart + _afterPart;
}
};
STDMETHODIMP CHandler::Open(IInStream *stream,
const UINT64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
Close();
try
{
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
CVolumeName seqName;
if (openArchiveCallback != NULL)
{
openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
UINT64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
while(true)
{
CMyComPtr<IInStream> inStream;
if (!_archives.IsEmpty())
{
if (!openVolumeCallback)
break;
if(_archives.Size() == 1)
{
if (!_archiveInfo.IsVolume())
break;
UString baseName;
{
NCOM::CPropVariant propVariant;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
if (propVariant.vt != VT_BSTR)
break;
baseName = propVariant.bstrVal;
}
seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName());
}
UString fullName = seqName.GetNextName();
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
if (result == S_FALSE)
break;
if (result != S_OK)
return result;
if (!stream)
break;
}
else
inStream = stream;
NArchive::NRar::CInArchive archive;
if(!archive.Open(inStream, maxCheckStartPosition))
return S_FALSE;
if (_archives.IsEmpty())
{
archive.GetArchiveInfo(_archiveInfo);
}
CItemEx item;
while(archive.GetNextItem(item))
{
if (item.IgnoreItem())
continue;
bool needAdd = true;
if (item.IsSplitBefore())
{
if (!_refItems.IsEmpty())
{
CRefItem &refItem = _refItems.Back();
refItem.NumItems++;
needAdd = false;
}
}
if (needAdd)
{
CRefItem refItem;
refItem.ItemIndex = _items.Size();
refItem.NumItems = 1;
refItem.VolumeIndex = _archives.Size();
_refItems.Add(refItem);
}
_items.Add(item);
if (openArchiveCallback != NULL)
{
UINT64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
}
_archives.Add(archive);
}
}
catch(...)
{
return S_FALSE;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
COM_TRY_BEGIN
_refItems.Clear();
_items.Clear();
_archives.Clear();
return S_OK;
COM_TRY_END
}
struct CMethodItem
{
BYTE RarUnPackVersion;
CMyComPtr<ICompressCoder> Coder;
};
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
INT32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
{
COM_TRY_BEGIN
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
bool testMode = (_aTestMode != 0);
CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
UINT64 censoredTotalUnPacked = 0,
// censoredTotalPacked = 0,
importantTotalUnPacked = 0;
// importantTotalPacked = 0;
bool allFilesMode = (numItems == UINT32(-1));
if (allFilesMode)
numItems = _refItems.Size();
if(numItems == 0)
return S_OK;
int lastIndex = 0;
CRecordVector<int> importantIndexes;
CRecordVector<bool> extractStatuses;
for(UINT32 t = 0; t < numItems; t++)
{
int index = allFilesMode ? t : indices[t];
const CRefItem &refItem = _refItems[index];
const CItemEx &item = _items[refItem.ItemIndex];
censoredTotalUnPacked += item.UnPackSize;
// censoredTotalPacked += item.PackSize;
for(int j = lastIndex; j <= index; j++)
// if(!_items[_refItems[j].ItemIndex].IsSolid())
if(!IsSolid(j))
lastIndex = j;
for(j = lastIndex; j <= index; j++)
{
const CRefItem &refItem = _refItems[j];
const CItemEx &item = _items[refItem.ItemIndex];
// const CItemEx &item = _items[j];
importantTotalUnPacked += item.UnPackSize;
// importantTotalPacked += item.PackSize;
importantIndexes.Add(j);
extractStatuses.Add(j == index);
}
lastIndex = index + 1;
}
extractCallback->SetTotal(importantTotalUnPacked);
UINT64 currentImportantTotalUnPacked = 0;
UINT64 currentImportantTotalPacked = 0;
UINT64 currentUnPackSize, currentPackSize;
/*
CSysString path = GetCodecsFolderPrefix() + TEXT("Rar29.dll");
TCHAR compressLibPath[MAX_PATH + 64];
if (!GetCompressFolderPrefix(compressLibPath))
return ::GetLastError();
lstrcat(compressLibPath, TEXT("Rar29.dll"));
*/
N7z::LoadMethodMap();
CCoderLibraries libraries;
CObjectVector<CMethodItem> methodItems;
/*
CCoderLibrary compressLib;
CMyComPtr<ICompressCoder> decoder15;
CMyComPtr<ICompressCoder> decoder20;
CMyComPtr<ICompressCoder> decoder29;
*/
NCompress::CCopyCoder *copyCoderSpec = NULL;
CMyComPtr<ICompressCoder> copyCoder;
CCoderMixer *mixerCoderSpec;
CMyComPtr<ICompressCoder> mixerCoder;
bool mixerCoderStoreMethod;
int mixerCryptoVersion;
CMyComPtr<ICompressCoder> rar20CryptoDecoder;
CMyComPtr<ICompressCoder> rar29CryptoDecoder;
CFolderInStream *folderInStreamSpec = NULL;
CMyComPtr<ISequentialInStream> folderInStream;
for(int i = 0; i < importantIndexes.Size(); i++,
currentImportantTotalUnPacked += currentUnPackSize,
currentImportantTotalPacked += currentPackSize)
{
RINOK(extractCallback->SetCompleted(
&currentImportantTotalUnPacked));
CMyComPtr<ISequentialOutStream> realOutStream;
INT32 askMode;
if(extractStatuses[i])
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract;
else
askMode = NArchive::NExtract::NAskMode::kSkip;
UINT32 index = importantIndexes[i];
const CRefItem &refItem = _refItems[index];
const CItemEx &item = _items[refItem.ItemIndex];
currentUnPackSize = item.UnPackSize;
currentPackSize = GetPackSize(index);
if(item.IgnoreItem())
continue;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if(item.IsDirectory())
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue;
}
bool mustBeProcessedAnywhere = false;
if(i < importantIndexes.Size() - 1)
{
// const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]];
// const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex];
// mustBeProcessedAnywhere = nextItemInfo.IsSolid();
mustBeProcessedAnywhere = IsSolid(importantIndexes[i + 1]);
}
if (!mustBeProcessedAnywhere && !testMode && !realOutStream)
continue;
if (!realOutStream && !testMode)
askMode = NArchive::NExtract::NAskMode::kSkip;
RINOK(extractCallback->PrepareOperation(askMode));
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream);
realOutStream.Release();
UINT64 packedPos = currentImportantTotalPacked;
UINT64 unpackedPos = currentImportantTotalUnPacked;
/*
for (int partIndex = 0; partIndex < 1; partIndex++)
{
CMyComPtr<ISequentialInStream> inStream;
// item redefinition
const CItemEx &item = _items[refItem.ItemIndex + partIndex];
NArchive::NRar::CInArchive &archive = _archives[refItem.VolumeIndex + partIndex];
inStream.Attach(archive.CreateLimitedStream(item.GetDataPosition(),
item.PackSize));
*/
if (!folderInStream)
{
folderInStreamSpec = new CFolderInStream;
folderInStream = folderInStreamSpec;
}
folderInStreamSpec->Init(&_archives, &_items, refItem);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&packedPos,
&unpackedPos);
UINT64 packSize = currentPackSize;
// packedPos += item.PackSize;
// unpackedPos += 0;
if (item.IsEncrypted())
{
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
if (item.UnPackVersion >= 29)
{
if (!rar29CryptoDecoder)
{
rar29CryptoDecoder = new NCrypto::NRar29::CDecoder();
// RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder));
}
CMyComPtr<ICompressSetDecoderProperties> cryptoProperties;
RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties,
&cryptoProperties));
CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec);
inStreamSpec->Init(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0);
RINOK(cryptoProperties->SetDecoderProperties(inStreamProperties));
RINOK(rar29CryptoDecoder.QueryInterface(IID_ICryptoSetPassword,
&cryptoSetPassword));
}
else if (item.UnPackVersion >= 20)
{
if (!rar20CryptoDecoder)
{
rar20CryptoDecoder = new NCrypto::NRar20::CDecoder();
// RINOK(rar20CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar20Decoder));
}
RINOK(rar20CryptoDecoder.QueryInterface(IID_ICryptoSetPassword,
&cryptoSetPassword));
}
else
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
if (!getTextPassword)
extractCallback.QueryInterface(IID_ICryptoGetTextPassword,
&getTextPassword);
if (getTextPassword)
{
CMyComBSTR password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
if (item.UnPackVersion >= 29)
{
RINOK(cryptoSetPassword->CryptoSetPassword(
(const BYTE *)(const wchar_t *)password,
password.Length() * sizeof(wchar_t)));
}
else
{
AString oemPassword = UnicodeStringToMultiByte(
(const wchar_t *)password, CP_OEMCP);
RINOK(cryptoSetPassword->CryptoSetPassword(
(const BYTE *)(const char *)oemPassword, oemPassword.Length()));
}
}
else
{
RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
}
}
switch(item.Method)
{
case '0':
{
if(copyCoderSpec == NULL)
{
copyCoderSpec = new NCompress::CCopyCoder;
copyCoder = copyCoderSpec;
}
if (item.IsEncrypted())
{
{
if (!mixerCoder || !mixerCoderStoreMethod ||
item.UnPackVersion != mixerCryptoVersion)
{
mixerCoder.Release();
mixerCoderSpec = new CCoderMixer;
mixerCoder = mixerCoderSpec;
if (item.UnPackVersion >= 29)
mixerCoderSpec->AddCoder(rar29CryptoDecoder);
else
mixerCoderSpec->AddCoder(rar20CryptoDecoder);
mixerCoderSpec->AddCoder(copyCoder);
mixerCoderSpec->FinishAddingCoders();
mixerCoderStoreMethod = true;
mixerCryptoVersion = item.UnPackVersion;
}
mixerCoderSpec->ReInit();
mixerCoderSpec->SetCoderInfo(0, &packSize, &item.UnPackSize);
mixerCoderSpec->SetCoderInfo(1, &item.UnPackSize, &item.UnPackSize);
mixerCoderSpec->SetProgressCoderIndex(1);
RINOK(mixerCoder->Code(folderInStream, outStream,
NULL, NULL, compressProgress));
}
}
else
{
RINOK(copyCoder->Code(folderInStream, outStream,
NULL, NULL, compressProgress));
}
break;
}
case '1':
case '2':
case '3':
case '4':
case '5':
{
/*
if (item.UnPackVersion >= 29)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
*/
int m;
for (m = 0; m < methodItems.Size(); m++)
if (methodItems[m].RarUnPackVersion == item.UnPackVersion)
break;
if (m == methodItems.Size())
{
CMethodItem mi;
mi.RarUnPackVersion = item.UnPackVersion;
N7z::CMethodID methodID = { { 0x04, 0x03 } , 3 };
BYTE myID;
if (item.UnPackVersion < 20)
myID = 1;
else if (item.UnPackVersion < 29)
myID = 2;
else
myID = 3;
methodID.ID[2] = myID;
N7z::CMethodInfo methodInfo;
if (!N7z::GetMethodInfo(methodID, methodInfo))
{
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
RINOK(libraries.CreateCoder(methodInfo.FilePath,
methodInfo.Decoder, &mi.Coder));
m = methodItems.Add(mi);
}
CMyComPtr<ICompressCoder> decoder = methodItems[m].Coder;
CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties;
RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties,
&compressSetDecoderProperties));
BYTE isSolid = (
// item.IsSolid()
IsSolid(index)
||
item.IsSplitBefore())
? 1: 0;
CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec);
inStreamSpec->Init(&isSolid, 1);
RINOK(compressSetDecoderProperties->SetDecoderProperties(inStreamProperties));
HRESULT result;
if (item.IsEncrypted())
{
if (!mixerCoder || mixerCoderStoreMethod)
{
mixerCoder.Release();
mixerCoderSpec = new CCoderMixer;
mixerCoder = mixerCoderSpec;
if (item.UnPackVersion >= 29)
mixerCoderSpec->AddCoder(rar29CryptoDecoder);
else
mixerCoderSpec->AddCoder(rar20CryptoDecoder);
mixerCoderSpec->AddCoder(decoder);
mixerCoderSpec->FinishAddingCoders();
mixerCoderStoreMethod = false;
}
mixerCoderSpec->ReInit();
mixerCoderSpec->SetCoderInfo(1, &packSize,
&item.UnPackSize);
mixerCoderSpec->SetProgressCoderIndex(1);
result = mixerCoder->Code(folderInStream, outStream,
NULL, NULL, compressProgress);
}
else
{
result = decoder->Code(folderInStream, outStream,
&packSize, &item.UnPackSize, compressProgress);
}
if (result == S_FALSE)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
if (result != S_OK)
return result;
break;
}
default:
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
/*
if (refItem.NumItems == 1 &&
!item.IsSplitBefore() && !item.IsSplitAfter())
*/
{
const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC;
outStream.Release();
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
NArchive::NExtract::NOperationResult::kCRCError));
}
/*
else
{
bool crcOK = true;
for (int partIndex = 0; partIndex < refItem.NumItems; partIndex++)
{
const CItemEx &item = _items[refItem.ItemIndex + partIndex];
if (item.FileCRC != folderInStreamSpec->CRCs[partIndex])
{
crcOK = false;
break;
}
}
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
NArchive::NExtract::NOperationResult::kCRCError));
}
*/
}
return S_OK;
COM_TRY_END
}
/*
STDMETHODIMP CHandler::ExtractAllItems(INT32 testMode,
IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
CRecordVector<UINT32> indices;
indices.Reserve(_refItems.Size());
for(int i = 0; i < _refItems.Size(); i++)
indices.Add(i);
return Extract(&indices.Front(), _refItems.Size(), testMode, extractCallback);
COM_TRY_END
}
*/
}}

65
7zip/Archive/Rar/RarHandler.h Executable file
View File

@@ -0,0 +1,65 @@
// Rar/Handler.h
#pragma once
#ifndef __RAR_HANDLER_H
#define __RAR_HANDLER_H
#include "../IArchive.h"
#include "RarIn.h"
#include "RarVolumeInStream.h"
namespace NArchive {
namespace NRar {
class CHandler:
public IInArchive,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Open)(IInStream *aStream,
const UINT64 *aMaxCheckStartPosition,
IArchiveOpenCallback *anOpenArchiveCallback);
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);
private:
CRecordVector<CRefItem> _refItems;
CObjectVector<CItemEx> _items;
CObjectVector<CInArchive> _archives;
NArchive::NRar::CInArchiveInfo _archiveInfo;
UINT64 GetPackSize(int refIndex) const;
// NArchive::NRar::CInArchive _archive;
bool IsSolid(int refIndex)
{
const CItemEx &item = _items[_refItems[refIndex].ItemIndex];
if (item.UnPackVersion < 20)
{
if (_archiveInfo.IsSolid())
return (refIndex > 0);
return false;
}
return item.IsSolid();
}
};
}}
#endif

64
7zip/Archive/Rar/RarHeader.cpp Executable file
View File

@@ -0,0 +1,64 @@
// Archive::Rar::Headers.cpp
#include "StdAfx.h"
#include "RarHeader.h"
#include "Common/CRC.h"
static void UpdateCRCBytesWithoutStartBytes(CCRC &crc, const void *data,
UINT32 size, UINT32 exludeSize)
{
crc.Update(((const BYTE *)data) + exludeSize, size - exludeSize);
}
namespace NArchive{
namespace NRar{
namespace NHeader{
BYTE kMarker[kMarkerSize] = {0x52 + 1, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
class CMarkerInitializer
{
public:
CMarkerInitializer() { kMarker[0]--; };
};
static CMarkerInitializer aMarkerInitializer;
namespace NArchive
{
UINT16 CBlock::GetRealCRC() const
{
CCRC crc;
UpdateCRCBytesWithoutStartBytes(crc, this,
sizeof(*this), sizeof(CRC));
return UINT16(crc.GetDigest());
}
}
namespace NFile
{
/*
UINT16 CBlock32::GetRealCRC(const void *aName, UINT32 aNameSize,
bool anExtraDataDefined, BYTE *anExtraData) const
{
CCRC crc;
UpdateCRCBytesWithoutStartBytes(crc, this,
sizeof(*this), sizeof(HeadCRC));
crc.Update(aName, aNameSize);
if (anExtraDataDefined)
crc.Update(anExtraData, 8);
return UINT16(crc.GetDigest());
}
UINT16 CBlock64::GetRealCRC(const void *aName, UINT32 aNameSize) const
{
CCRC crc;
UpdateCRCBytesWithoutStartBytes(crc, this,
sizeof(*this), sizeof(HeadCRC));
crc.Update(aName, aNameSize);
return UINT16(crc.GetDigest());
}
*/
}
}}}

214
7zip/Archive/Rar/RarHeader.h Executable file
View File

@@ -0,0 +1,214 @@
// Archive::Rar::Header.h
#pragma once
#ifndef __ARCHIVE_RAR_HEADER_H
#define __ARCHIVE_RAR_HEADER_H
#include "Common/Types.h"
#pragma pack(push, PragmaRarHeaders)
#pragma pack(push, 1)
namespace NArchive{
namespace NRar{
namespace NHeader{
const int kMarkerSize = 7;
extern BYTE kMarker[kMarkerSize];
const int kArchiveSolid = 0x1;
namespace NBlockType
{
enum EBlockType
{
kMarker = 0x72,
kArchiveHeader = 0x73,
kFileHeader = 0x74,
kCommentHeader = 0x75,
kOldAuthenticity = 0x76,
kSubBlock = 0x77,
kRecoveryRecord = 0x78,
kAuthenticity = 0x79,
kEndOfArchive = 0x7B // Is not safe
};
}
namespace NArchive
{
const UINT16 kVolume = 1;
const UINT16 kComment = 2;
const UINT16 kLock = 4;
const UINT16 kSolid = 8;
const UINT16 kNewVolName = 0x10; // ('volname.partN.rar')
const UINT16 kAuthenticity = 0x20;
const UINT16 kRecovery = 0x40;
const UINT16 kBlockEncryption = 0x80;
const UINT16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later)
struct CBlock
{
UINT16 CRC;
BYTE Type;
UINT16 Flags;
UINT16 Size;
UINT16 Reserved1;
UINT32 Reserved2;
UINT16 GetRealCRC() const;
};
const int kBlockHeadersAreEncrypted = 0x80;
}
namespace NFile
{
const int kSplitBefore = 1 << 0;
const int kSplitAfter = 1 << 1;
const int kEncrypted = 1 << 2;
const int kComment = 1 << 3;
const int kSolid = 1 << 4;
const int kDictBitStart = 5;
const int kNumDictBits = 3;
const int kDictMask = (1 << kNumDictBits) - 1;
const int kDictDirectoryValue = 0x7;
const int kSize64Bits = 1 << 8;
const int kUnicodeName = 1 << 9;
const int kSalt = 1 << 10;
const int kOldVersion = 1 << 11;
const int kExtTime = 1 << 12;
// const int kExtFlags = 1 << 13;
// const int kSkipIfUnknown = 1 << 14;
const int kLongBlock = 1 << 15;
struct CBlock
{
// UINT16 HeadCRC;
// BYTE Type;
// UINT16 Flags;
// UINT16 HeadSize;
UINT32 PackSize;
UINT32 UnPackSize;
BYTE HostOS;
UINT32 FileCRC;
UINT32 Time;
BYTE UnPackVersion;
BYTE Method;
UINT16 NameSize;
UINT32 Attributes;
};
/*
struct CBlock32
{
UINT16 HeadCRC;
BYTE Type;
UINT16 Flags;
UINT16 HeadSize;
UINT32 PackSize;
UINT32 UnPackSize;
BYTE HostOS;
UINT32 FileCRC;
UINT32 Time;
BYTE UnPackVersion;
BYTE Method;
UINT16 NameSize;
UINT32 Attributes;
UINT16 GetRealCRC(const void *aName, UINT32 aNameSize,
bool anExtraDataDefined = false, BYTE *anExtraData = 0) const;
};
struct CBlock64
{
UINT16 HeadCRC;
BYTE Type;
UINT16 Flags;
UINT16 HeadSize;
UINT32 PackSizeLow;
UINT32 UnPackSizeLow;
BYTE HostOS;
UINT32 FileCRC;
UINT32 Time;
BYTE UnPackVersion;
BYTE Method;
UINT16 NameSize;
UINT32 Attributes;
UINT32 PackSizeHigh;
UINT32 UnPackSizeHigh;
UINT16 GetRealCRC(const void *aName, UINT32 aNameSize) const;
};
*/
const int kLabelFileAttribute = 0x08;
const int kWinFileDirectoryAttributeMask = 0x10;
enum CHostOS
{
kHostMSDOS = 0,
kHostOS2 = 1,
kHostWin32 = 2,
kHostUnix = 3,
kHostMacOS = 4,
kHostBeOS = 5
};
}
namespace NBlock
{
const UINT16 kLongBlock = 1 << 15;
struct CBlock
{
UINT16 CRC;
BYTE Type;
UINT16 Flags;
UINT16 HeadSize;
// UINT32 DataSize;
};
}
struct CSubBlock
{
UINT16 HeadCRC;
BYTE HeadType;
UINT16 Flags;
UINT16 HeadSize;
UINT32 DataSize;
UINT16 SubType;
BYTE Level; // Reserved : Must be 0
};
struct CCommentBlock
{
UINT16 HeadCRC;
BYTE HeadType;
UINT16 Flags;
UINT16 HeadSize;
UINT16 UnpSize;
BYTE UnpVer;
BYTE Method;
UINT16 CommCRC;
};
struct CProtectHeader
{
UINT16 HeadCRC;
BYTE HeadType;
UINT16 Flags;
UINT16 HeadSize;
UINT32 DataSize;
BYTE Version;
UINT16 RecSectors;
UINT32 TotalBlocks;
BYTE Mark[8];
};
}}}
#pragma pack(pop)
#pragma pack(pop, PragmaRarHeaders)
#endif

407
7zip/Archive/Rar/RarIn.cpp Executable file
View File

@@ -0,0 +1,407 @@
// Archive/RarIn.cpp
#include "StdAfx.h"
#include "Common/StringConvert.h"
#include "Common/CRC.h"
#include "RarIn.h"
#include "../../Common/LimitedStreams.h"
namespace NArchive {
namespace NRar {
static const char kEndOfString = '\0';
void CInArchive::ThrowExceptionWithCode(
CInArchiveException::CCauseType cause)
{
throw CInArchiveException(cause);
}
bool CInArchive::Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit)
{
if(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK)
return false;
m_Position = m_StreamStartPosition;
m_Stream = inStream;
if (ReadMarkerAndArchiveHeader(searchHeaderSizeLimit))
return true;
m_Stream.Release();
return false;
}
void CInArchive::Close()
{
m_Stream.Release();
}
static inline bool TestMarkerCandidate(const void *aTestBytes)
{
// return (memcmp(aTestBytes, NHeader::kMarker, NHeader::kMarkerSize) == 0);
for (UINT32 i = 0; i < NHeader::kMarkerSize; i++)
if (((const BYTE *)aTestBytes)[i] != NHeader::kMarker[i])
return false;
return true;
}
bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
{
// if (m_Length < NHeader::kMarkerSize)
// return false;
m_ArchiveStartPosition = 0;
m_Position = m_StreamStartPosition;
if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
return false;
BYTE marker[NHeader::kMarkerSize];
UINT32 processedSize;
ReadBytes(marker, NHeader::kMarkerSize, &processedSize);
if(processedSize != NHeader::kMarkerSize)
return false;
if (TestMarkerCandidate(marker))
return true;
CByteDynamicBuffer dynamicBuffer;
static const UINT32 kSearchMarkerBufferSize = 0x10000;
dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize);
BYTE *buffer = dynamicBuffer;
UINT32 numBytesPrev = NHeader::kMarkerSize - 1;
memmove(buffer, marker + 1, numBytesPrev);
UINT64 curTestPos = m_StreamStartPosition + 1;
while(true)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
return false;
UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
UINT32 numBytesInBuffer = numBytesPrev + processedSize;
if (numBytesInBuffer < NHeader::kMarkerSize)
return false;
UINT32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1;
for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++)
{
if (TestMarkerCandidate(buffer + pos))
{
m_ArchiveStartPosition = curTestPos;
m_Position = curTestPos + NHeader::kMarkerSize;
if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK)
return false;
return true;
}
}
numBytesPrev = numBytesInBuffer - numTests;
memmove(buffer, buffer + numTests, numBytesPrev);
}
return false;
}
//bool boolIsItCorrectArchive;
void CInArchive::ThrowUnexpectedEndOfArchiveException()
{
ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive);
}
bool CInArchive::ReadBytesAndTestSize(void *data, UINT32 size)
{
UINT32 processedSize;
m_Stream->Read(data, size, &processedSize);
return (processedSize == size);
}
void CInArchive::ReadBytesAndTestResult(void *data, UINT32 size)
{
if(!ReadBytesAndTestSize(data,size))
ThrowUnexpectedEndOfArchiveException();
}
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
{
UINT32 realProcessedSize;
HRESULT result = m_Stream->Read(data, size, &realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
AddToSeekValue(realProcessedSize);
return result;
}
bool CInArchive::ReadMarkerAndArchiveHeader(const UINT64 *searchHeaderSizeLimit)
{
if (!FindAndReadMarker(searchHeaderSizeLimit))
return false;
UINT32 processedSize;
ReadBytes(&m_ArchiveHeader, sizeof(m_ArchiveHeader), &processedSize);
if (processedSize != sizeof(m_ArchiveHeader))
return false;
if(m_ArchiveHeader.CRC != m_ArchiveHeader.GetRealCRC())
ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError);
if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader)
return false;
m_ArchiveCommentPosition = m_Position;
m_SeekOnArchiveComment = true;
return true;
}
void CInArchive::SkipArchiveComment()
{
if (!m_SeekOnArchiveComment)
return;
AddToSeekValue(m_ArchiveHeader.Size - sizeof(m_ArchiveHeader));
m_SeekOnArchiveComment = false;
}
void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
{
archiveInfo.StartPosition = m_ArchiveStartPosition;
archiveInfo.Flags = m_ArchiveHeader.Flags;
archiveInfo.CommentPosition = m_ArchiveCommentPosition;
archiveInfo.CommentSize = m_ArchiveHeader.Size - sizeof(m_ArchiveHeader);
}
static void DecodeUnicodeFileName(const char *name, const BYTE *encName,
int encSize, wchar_t *unicodeName, int maxDecSize)
{
int encPos = 0;
int decPos = 0;
int flagBits = 0;
BYTE flags = 0;
BYTE highByte = encName[encPos++];
while (encPos < encSize && decPos < maxDecSize)
{
if (flagBits == 0)
{
flags = encName[encPos++];
flagBits = 8;
}
switch(flags >> 6)
{
case 0:
unicodeName[decPos++] = encName[encPos++];
break;
case 1:
unicodeName[decPos++] = encName[encPos++] + (highByte << 8);
break;
case 2:
unicodeName[decPos++] = encName[encPos] + (encName[encPos + 1] << 8);
encPos += 2;
break;
case 3:
{
int length = encName[encPos++];
if (length & 0x80)
{
BYTE correction = encName[encPos++];
for (length = (length & 0x7f) + 2;
length > 0 && decPos < maxDecSize; length--, decPos++)
unicodeName[decPos] = ((name[decPos] + correction) & 0xff) + (highByte << 8);
}
else
for (length += 2; length > 0 && decPos < maxDecSize; length--, decPos++)
unicodeName[decPos] = name[decPos];
}
break;
}
flags <<= 2;
flagBits -= 2;
}
unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0;
}
void CInArchive::ReadName(const BYTE *data, CItemEx &item, int nameSize)
{
int sizeFileName = nameSize;
item.UnicodeName.Empty();
if (sizeFileName > 0)
{
m_NameBuffer.EnsureCapacity(sizeFileName + 1);
char *buffer = (char *)m_NameBuffer;
memmove(buffer, data, sizeFileName);
int mainLen;
for (mainLen = 0; mainLen < sizeFileName; mainLen++)
if (buffer[mainLen] == '\0')
break;
buffer[mainLen] = '\0';
item.Name = buffer;
int unicodeNameSizeMax = MyMin(sizeFileName, (0x400));
_unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
if((m_BlockHeader.Flags & NHeader::NFile::kUnicodeName) != 0 &&
mainLen < sizeFileName)
{
DecodeUnicodeFileName(buffer, (const BYTE *)buffer + mainLen + 1,
sizeFileName - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
item.UnicodeName = _unicodeNameBuffer;
}
}
else
item.Name.Empty();
}
static const BYTE *ReadTime(const BYTE *data, BYTE mask, CRarTime &rarTime)
{
rarTime.LowSecond = ((mask & 4) != 0) ? 1 : 0;
int numDigits = (mask & 3);
rarTime.SubTime[0] = rarTime.SubTime[1] = rarTime.SubTime[2] = 0;
for (int i = 0; i < numDigits; i++)
rarTime.SubTime[3 - numDigits + i] = *data++;
return data;
}
void CInArchive::ReadHeaderReal(const BYTE *data, CItemEx &item)
{
const BYTE *dataStart = data;
const NHeader::NFile::CBlock &fileHeader =
*(const NHeader::NFile::CBlock *)data;
// UINT32 sizeFileName = fileHeader.NameSize;
item.Flags = m_BlockHeader.Flags;
item.PackSize = fileHeader.PackSize;
item.UnPackSize = fileHeader.UnPackSize;
item.HostOS = fileHeader.HostOS;
item.FileCRC = fileHeader.FileCRC;
item.LastWriteTime.DosTime = fileHeader.Time;
item.LastWriteTime.LowSecond = 0;
item.LastWriteTime.SubTime[0] =
item.LastWriteTime.SubTime[1] =
item.LastWriteTime.SubTime[2] = 0;
item.UnPackVersion = fileHeader.UnPackVersion;
item.Method = fileHeader.Method;
item.Attributes = fileHeader.Attributes;
data += sizeof(fileHeader);
if((item.Flags & NHeader::NFile::kSize64Bits) != 0)
{
item.PackSize |= (*((const UINT64 *)data)) << 32;
data += sizeof(UINT32);
item.UnPackSize |= (*((const UINT64 *)data)) << 32;
data += sizeof(UINT32);
}
ReadName(data, item, fileHeader.NameSize);
data += fileHeader.NameSize;
if (item.HasSalt())
{
memmove(item.Salt, data, sizeof(item.Salt));
data += sizeof(item.Salt);
}
if (item.HasExtTime())
{
BYTE access = (*data) >> 4;
data++;
BYTE modif = (*data) >> 4;
BYTE creat = (*data) & 0xF;
data++;
if ((modif & 8) != 0)
data = ReadTime(data, modif, item.LastWriteTime);
if (item.IsCreationTimeDefined = ((creat & 8) != 0))
{
item.CreationTime.DosTime = *(const UINT32 *)data;
data += sizeof(UINT32);
data = ReadTime(data, creat, item.CreationTime);
}
if (item.IsLastAccessTimeDefined = ((access & 8) != 0))
{
item.LastAccessTime.DosTime = *(const UINT32 *)data;
data += sizeof(UINT32);
data = ReadTime(data, access, item.LastAccessTime);
}
}
UINT16 fileHeaderWithNameSize =
sizeof(NHeader::NBlock::CBlock) + data - dataStart;
item.Position = m_Position;
item.MainPartSize = fileHeaderWithNameSize;
item.CommentSize = m_BlockHeader.HeadSize - fileHeaderWithNameSize;
AddToSeekValue(m_BlockHeader.HeadSize);
}
void CInArchive::AddToSeekValue(UINT64 addValue)
{
m_Position += addValue;
}
bool CInArchive::GetNextItem(CItemEx &item)
{
if ((m_ArchiveHeader.Flags &
NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
return false;
if (m_SeekOnArchiveComment)
SkipArchiveComment();
while (true)
{
if(!SeekInArchive(m_Position))
return false;
if(!ReadBytesAndTestSize(&m_BlockHeader, sizeof(m_BlockHeader)))
return false;
if (m_BlockHeader.HeadSize < 7)
ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive);
if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader)
{
m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize);
UINT32 headerSize = m_BlockHeader.HeadSize - sizeof(m_BlockHeader);
ReadBytesAndTestResult(m_FileHeaderData, headerSize);
CCRC crc;
crc.Update(&m_BlockHeader.Type, sizeof(m_BlockHeader) -
sizeof(m_BlockHeader.CRC));
ReadHeaderReal(m_FileHeaderData, item);
crc.Update(m_FileHeaderData, headerSize - item.CommentSize);
if ((crc.GetDigest() & 0xFFFF) != m_BlockHeader.CRC)
ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError);
SeekInArchive(m_Position); // Move Position to compressed Data;
AddToSeekValue(item.PackSize); // m_Position points Tto next header;
return true;
}
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
{
UINT32 dataSize;
ReadBytesAndTestResult(&dataSize, sizeof(dataSize)); // test it
AddToSeekValue(dataSize);
}
AddToSeekValue(m_BlockHeader.HeadSize);
}
}
void CInArchive::DirectGetBytes(void *data, UINT32 size)
{
m_Stream->Read(data, size, NULL);
}
bool CInArchive::SeekInArchive(UINT64 position)
{
UINT64 newPosition;
m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition);
return newPosition == position;
}
ISequentialInStream* CInArchive::CreateLimitedStream(UINT64 position, UINT64 size)
{
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
SeekInArchive(position);
streamSpec->Init(m_Stream, size);
return inStream.Detach();
}
}}

96
7zip/Archive/Rar/RarIn.h Executable file
View File

@@ -0,0 +1,96 @@
// RarIn.h
#pragma once
#ifndef __ARCHIVE_RAR_IN_H
#define __ARCHIVE_RAR_IN_H
#include "Common/DynamicBuffer.h"
#include "Common/Exception.h"
#include "Common/MyCom.h"
#include "../../IStream.h"
#include "RarHeader.h"
#include "RarItem.h"
namespace NArchive {
namespace NRar {
class CInArchiveException
{
public:
enum CCauseType
{
kUnexpectedEndOfArchive = 0,
kArchiveHeaderCRCError,
kFileHeaderCRCError,
kIncorrectArchive,
}
Cause;
CInArchiveException(CCauseType cause) : Cause(cause) {}
};
class CInArchiveInfo
{
public:
UINT64 StartPosition;
WORD Flags;
UINT64 CommentPosition;
WORD CommentSize;
bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; }
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }
bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; }
};
class CInArchive
{
CMyComPtr<IInStream> m_Stream;
UINT64 m_StreamStartPosition;
UINT64 m_Position;
UINT64 m_ArchiveStartPosition;
NHeader::NArchive::CBlock m_ArchiveHeader;
CDynamicBuffer<char> m_NameBuffer;
CDynamicBuffer<wchar_t> _unicodeNameBuffer;
bool m_SeekOnArchiveComment;
UINT64 m_ArchiveCommentPosition;
void ReadName(const BYTE *data, CItemEx &item, int nameSize);
void ReadHeaderReal(const BYTE *data, CItemEx &item);
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *aProcessedSize);
bool ReadBytesAndTestSize(void *data, UINT32 size);
void ReadBytesAndTestResult(void *data, UINT32 size);
bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit);
void ThrowExceptionWithCode(CInArchiveException::CCauseType cause);
void ThrowUnexpectedEndOfArchiveException();
void AddToSeekValue(UINT64 addValue);
protected:
CDynamicBuffer<BYTE> m_FileHeaderData;
NHeader::NBlock::CBlock m_BlockHeader;
bool ReadMarkerAndArchiveHeader(const UINT64 *searchHeaderSizeLimit);
public:
bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit);
void Close();
bool GetNextItem(CItemEx &item);
void SkipArchiveComment();
void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
void DirectGetBytes(void *data, UINT32 size);
bool SeekInArchive(UINT64 position);
ISequentialInStream *CreateLimitedStream(UINT64 position, UINT64 size);
};
}}
#endif

108
7zip/Archive/Rar/RarItem.cpp Executable file
View File

@@ -0,0 +1,108 @@
// RarItem.cpp
#include "stdafx.h"
#include "RarItem.h"
#include "RarHeader.h"
namespace NArchive{
namespace NRar{
bool CItem::IsEncrypted() const
{ return (Flags & NHeader::NFile::kEncrypted) != 0; }
bool CItem::IsSolid() const
{ return (Flags & NHeader::NFile::kSolid) != 0; }
bool CItem::IsCommented() const
{ return (Flags & NHeader::NFile::kComment) != 0; }
bool CItem::IsSplitBefore() const
{ return (Flags & NHeader::NFile::kSplitBefore) != 0; }
bool CItem::IsSplitAfter() const
{ return (Flags & NHeader::NFile::kSplitAfter) != 0; }
bool CItem::HasSalt() const
{ return (Flags & NHeader::NFile::kSalt) != 0; }
bool CItem::HasExtTime() const
{ return (Flags & NHeader::NFile::kExtTime) != 0; }
bool CItem::HasUnicodeName() const
{ return (Flags & NHeader::NFile::kUnicodeName) != 0; }
bool CItem::IsOldVersion() const
{ return (Flags & NHeader::NFile::kOldVersion) != 0; }
bool CItem::IgnoreItem() const
{
switch(HostOS)
{
case NHeader::NFile::kHostMSDOS:
case NHeader::NFile::kHostOS2:
case NHeader::NFile::kHostWin32:
return ((Attributes & NHeader::NFile::kLabelFileAttribute) != 0);
}
return false;
}
UINT32 CItem::GetDictSize() const
{ return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; }
bool CItem::IsDirectory() const
{
return (GetDictSize() == NHeader::NFile::kDictDirectoryValue);
}
UINT32 CItem::GetWinAttributes() const
{
UINT32 aWinAttributes;
switch(HostOS)
{
case NHeader::NFile::kHostMSDOS:
case NHeader::NFile::kHostOS2:
case NHeader::NFile::kHostWin32:
aWinAttributes = Attributes;
break;
default:
aWinAttributes = 0; // must be converted from unix value;;
}
if (IsDirectory()) // test it;
aWinAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask;
return aWinAttributes;
}
void CItem::ClearFlags()
{ Flags = 0; }
void CItem::SetFlagBits(int aStartBitNumber, int aNumBits, int aValue)
{
UINT16 aMask = ((1 << aNumBits) - 1) << aStartBitNumber;
Flags &= ~aMask;
Flags |= aValue << aStartBitNumber;
}
void CItem::SetBitMask(int aBitMask, bool anEnable)
{
if(anEnable)
Flags |= aBitMask;
else
Flags &= ~aBitMask;
}
void CItem::SetDictSize(UINT32 aSize)
{
SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (aSize & NHeader::NFile::kDictMask));
}
void CItem::SetAsDirectory(bool aDirectory)
{
if (aDirectory)
SetDictSize(NHeader::NFile::kDictDirectoryValue);
}
void CItem::SetEncrypted(bool anEncrypted)
{ SetBitMask(NHeader::NFile::kEncrypted, anEncrypted); }
void CItem::SetSolid(bool aSolid)
{ SetBitMask(NHeader::NFile::kSolid, aSolid); }
void CItem::SetCommented(bool aCommented)
{ SetBitMask(NHeader::NFile::kComment, aCommented); }
void CItem::SetSplitBefore(bool aSplitBefore)
{ SetBitMask(NHeader::NFile::kSplitBefore, aSplitBefore); }
void CItem::SetSplitAfter(bool aSplitAfter)
{ SetBitMask(NHeader::NFile::kSplitAfter, aSplitAfter); }
}}

92
7zip/Archive/Rar/RarItem.h Executable file
View File

@@ -0,0 +1,92 @@
// RarItem.h
#pragma once
#ifndef __ARCHIVE_RAR_ITEM_H
#define __ARCHIVE_RAR_ITEM_H
#include "Common/Types.h"
#include "Common/String.h"
namespace NArchive{
namespace NRar{
struct CRarTime
{
UINT32 DosTime;
BYTE LowSecond;
BYTE SubTime[3];
};
class CItem
{
public:
UINT16 Flags;
UINT64 PackSize;
UINT64 UnPackSize;
BYTE HostOS;
UINT32 FileCRC;
CRarTime CreationTime;
CRarTime LastWriteTime;
CRarTime LastAccessTime;
bool IsCreationTimeDefined;
// bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
BYTE UnPackVersion;
BYTE Method;
UINT32 Attributes;
AString Name;
UString UnicodeName;
BYTE Salt[8];
bool IsEncrypted() const;
bool IsSolid() const;
bool IsCommented() const;
bool IsSplitBefore() const;
bool IsSplitAfter() const;
bool HasSalt() const;
bool HasExtTime() const;
bool HasUnicodeName() const;
bool IsOldVersion() const;
UINT32 GetDictSize() const;
bool IsDirectory() const;
bool IgnoreItem() const;
UINT32 GetWinAttributes() const;
CItem(): IsCreationTimeDefined(false), IsLastAccessTimeDefined(false) {}
private:
void SetFlagBits(int aStartBitNumber, int aNumBits, int aValue);
void SetBitMask(int aBitMask, bool anEnable);
public:
void ClearFlags();
void SetDictSize(UINT32 aSize);
void SetAsDirectory(bool aDirectory);
void SetEncrypted(bool anEncrypted);
void SetSolid(bool aSolid);
void SetCommented(bool aCommented);
void SetSplitBefore(bool aSplitBefore);
void SetSplitAfter(bool aSplitAfter);
};
class CItemEx: public CItem
{
public:
UINT64 Position;
UINT16 MainPartSize;
UINT16 CommentSize;
UINT64 GetFullSize() const { return MainPartSize + CommentSize + PackSize; };
// DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; };
UINT64 GetCommentPosition() const { return Position + MainPartSize; };
UINT64 GetDataPosition() const { return GetCommentPosition() + CommentSize; };
};
}}
#endif

19
7zip/Archive/Rar/RarItemEx.h Executable file
View File

@@ -0,0 +1,19 @@
// Archive::Rar::ItemInfoEx.h
#pragma once
#ifndef __ARCHIVE_RAR_ITEMINFOEX_H
#define __ARCHIVE_RAR_ITEMINFOEX_H
#include "Archive/Rar/ItemInfo.h"
namespace NArchive{
namespace NRar{
}}
#endif

View File

@@ -0,0 +1,83 @@
// RarVolumeInStream.cpp
#include "StdAfx.h"
#include "RarVolumeInStream.h"
#include "Windows/Defs.h"
#include "Common/Defs.h"
namespace NArchive {
namespace NRar {
void CFolderInStream::Init(
CObjectVector<CInArchive> *archives,
const CObjectVector<CItemEx> *items,
const CRefItem &refItem)
{
_archives = archives;
_items = items;
_refItem = refItem;
_curIndex = 0;
CRCs.Clear();
_fileIsOpen = false;
}
HRESULT CFolderInStream::OpenStream()
{
while (_curIndex < _refItem.NumItems)
{
const CItemEx &item = (*_items)[_refItem.ItemIndex + _curIndex];
_stream.Attach((*_archives)[_refItem.VolumeIndex + _curIndex].
CreateLimitedStream(item.GetDataPosition(), item.PackSize));
_curIndex++;
_fileIsOpen = true;
_crc.Init();
return S_OK;
}
return S_OK;
}
HRESULT CFolderInStream::CloseStream()
{
CRCs.Add(_crc.GetDigest());
_stream.Release();
_fileIsOpen = false;
return S_OK;
}
STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSize)
{
UINT32 realProcessedSize = 0;
while ((_curIndex < _refItem.NumItems || _fileIsOpen) && size > 0)
{
if (_fileIsOpen)
{
UINT32 localProcessedSize;
RINOK(_stream->Read(
((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
_crc.Update(((BYTE *)data) + realProcessedSize, localProcessedSize);
if (localProcessedSize == 0)
{
RINOK(CloseStream());
continue;
}
realProcessedSize += localProcessedSize;
size -= localProcessedSize;
}
else
{
RINOK(OpenStream());
}
}
if (processedSize != 0)
*processedSize = realProcessedSize;
return S_OK;
}
STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
{
return Read(data, size, processedSize);
}
}}

View File

@@ -0,0 +1,53 @@
// RarVolumeInStream.h
#pragma once
#ifndef __RAR_VOLUME_IN_STREAM_H
#define __RAR_VOLUME_IN_STREAM_H
#include "../../IStream.h"
#include "Common/CRC.h"
#include "RarIn.h"
namespace NArchive {
namespace NRar {
struct CRefItem
{
int VolumeIndex;
int ItemIndex;
int NumItems;
};
class CFolderInStream:
public ISequentialInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
private:
CObjectVector<CInArchive> *_archives;
const CObjectVector<CItemEx> *_items;
CRefItem _refItem;
int _curIndex;
CCRC _crc;
bool _fileIsOpen;
CMyComPtr<ISequentialInStream> _stream;
HRESULT OpenStream();
HRESULT CloseStream();
public:
void Init(CObjectVector<CInArchive> *archives,
const CObjectVector<CItemEx> *items,
const CRefItem &refItem);
CRecordVector<UINT32> CRCs;
};
}}
#endif

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

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

9
7zip/Archive/Rar/StdAfx.h Executable file
View File

@@ -0,0 +1,9 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include <time.h>
#endif

BIN
7zip/Archive/Rar/rar.ico Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

16
7zip/Archive/Rar/resource.h Executable file
View File

@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by resource.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

130
7zip/Archive/Rar/resource.rc Executable file
View File

@@ -0,0 +1,130 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Russian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Russian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,12,0,0
PRODUCTVERSION 3,12,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov \0"
VALUE "FileDescription", "Rar Plugin for 7-Zip\0"
VALUE "FileVersion", "3, 12, 0, 0\0"
VALUE "InternalName", "rar\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "rar.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "3, 12, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "Rar.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED