📄 7zhandler.cpp
字号:
// 7zHandler.cpp
#include "StdAfx.h"
#include "7zHandler.h"
#include "7zProperties.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/ComTry.h"
#include "../../../Windows/Defs.h"
#include "../Common/ItemNameUtils.h"
#ifdef _7Z_VOL
#include "../Common/MultiStream.h"
#endif
using namespace NWindows;
namespace NArchive {
namespace N7z {
CHandler::CHandler()
{
#ifndef EXTRACT_ONLY
Init();
#endif
#ifndef EXCLUDE_COM
LoadMethodMap();
#endif
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
COM_TRY_BEGIN
*numItems =
#ifdef _7Z_VOL
_refs.Size();
#else
*numItems = _database.Files.Size();
#endif
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
}
#ifdef _SFX
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{
return E_NOTIMPL;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
return E_NOTIMPL;
}
#endif
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{
*numProperties = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
return E_NOTIMPL;
}
static void MySetFileTime(bool timeDefined, FILETIME unixTime,
NWindows::NCOM::CPropVariant &propVariant)
{
if (timeDefined)
propVariant = unixTime;
}
/*
inline static wchar_t GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
}
static UString ConvertBytesToHexString(const Byte *data, UInt32 size)
{
UString result;
for (UInt32 i = 0; i < size; i++)
{
Byte b = data[i];
result += GetHex(b >> 4);
result += GetHex(b & 0xF);
}
return result;
}
*/
#ifndef _SFX
static UString ConvertUInt32ToString(UInt32 value)
{
wchar_t buffer[32];
ConvertUInt64ToString(value, buffer);
return buffer;
}
static UString GetStringForSizeValue(UInt32 value)
{
for (int i = 31; i >= 0; i--)
if ((UInt32(1) << i) == value)
return ConvertUInt32ToString(i);
UString result;
if (value % (1 << 20) == 0)
{
result += ConvertUInt32ToString(value >> 20);
result += L"m";
}
else if (value % (1 << 10) == 0)
{
result += ConvertUInt32ToString(value >> 10);
result += L"k";
}
else
{
result += ConvertUInt32ToString(value);
result += L"b";
}
return result;
}
static CMethodID k_Copy = { { 0x0 }, 1 };
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
static inline char GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
}
static inline UString GetHex2(Byte value)
{
UString result;
result += GetHex(value >> 4);
result += GetHex(value & 0xF);
return result;
}
#endif
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
/*
const CRef2 &ref2 = _refs[index];
if (ref2.Refs.IsEmpty())
return E_FAIL;
const CRef &ref = ref2.Refs.Front();
*/
#ifdef _7Z_VOL
const CRef &ref = _refs[index];
const CVolume &volume = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &_database = volume.Database;
UInt32 index2 = ref.ItemIndex;
const CFileItem &item = _database.Files[index2];
#else
const CFileItem &item = _database.Files[index];
UInt32 index2 = index;
#endif
switch(propID)
{
case kpidPath:
{
if (!item.Name.IsEmpty())
propVariant = NItemName::GetOSName(item.Name);
break;
}
case kpidIsFolder:
propVariant = item.IsDirectory;
break;
case kpidSize:
{
propVariant = item.UnPackSize;
// propVariant = ref2.UnPackSize;
break;
}
case kpidPosition:
{
/*
if (ref2.Refs.Size() > 1)
propVariant = ref2.StartPos;
else
*/
if (item.IsStartPosDefined)
propVariant = item.StartPos;
break;
}
case kpidPackedSize:
{
// propVariant = ref2.PackSize;
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
propVariant = _database.GetFolderFullPackSize(folderIndex);
/*
else
propVariant = UInt64(0);
*/
}
else
propVariant = UInt64(0);
}
break;
}
case kpidLastAccessTime:
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
break;
case kpidCreationTime:
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
break;
case kpidLastWriteTime:
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
break;
case kpidAttributes:
if (item.AreAttributesDefined)
propVariant = item.Attributes;
break;
case kpidCRC:
if (item.IsFileCRCDefined)
propVariant = item.FileCRC;
break;
#ifndef _SFX
case kpidMethod:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.Folders[folderIndex];
UString methodsString;
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
if (!methodsString.IsEmpty())
methodsString += L' ';
CMethodInfo methodInfo;
bool methodIsKnown;
for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
{
if (j > 0)
methodsString += L"|";
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
UString methodName;
#ifdef NO_REGISTRY
methodIsKnown = true;
if (altCoderInfo.MethodID == k_Copy)
methodName = L"Copy";
else if (altCoderInfo.MethodID == k_LZMA)
methodName = L"LZMA";
else if (altCoderInfo.MethodID == k_BCJ)
methodName = L"BCJ";
else if (altCoderInfo.MethodID == k_BCJ2)
methodName = L"BCJ2";
else if (altCoderInfo.MethodID == k_PPMD)
methodName = L"PPMD";
else if (altCoderInfo.MethodID == k_Deflate)
methodName = L"Deflate";
else if (altCoderInfo.MethodID == k_BZip2)
methodName = L"BZip2";
else
methodIsKnown = false;
#else
methodIsKnown = GetMethodInfo(
altCoderInfo.MethodID, methodInfo);
methodName = methodInfo.Name;
#endif
if (methodIsKnown)
{
methodsString += methodName;
if (altCoderInfo.MethodID == k_LZMA)
{
if (altCoderInfo.Properties.GetCapacity() >= 5)
{
methodsString += L":";
UInt32 dicSize = GetUInt32FromMemLE(
((const Byte *)altCoderInfo.Properties + 1));
methodsString += GetStringForSizeValue(dicSize);
}
}
else if (altCoderInfo.MethodID == k_PPMD)
{
if (altCoderInfo.Properties.GetCapacity() >= 5)
{
Byte order = *(const Byte *)altCoderInfo.Properties;
methodsString += L":o";
methodsString += ConvertUInt32ToString(order);
methodsString += L":mem";
UInt32 dicSize = GetUInt32FromMemLE(
((const Byte *)altCoderInfo.Properties + 1));
methodsString += GetStringForSizeValue(dicSize);
}
}
else
{
if (altCoderInfo.Properties.GetCapacity() > 0)
{
methodsString += L":[";
for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
{
if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
{
methodsString += L"..";
break;
}
else
methodsString += GetHex2(altCoderInfo.Properties[bi]);
}
methodsString += L"]";
}
}
}
else
{
methodsString += altCoderInfo.MethodID.ConvertToString();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -