// 7zProperties.cpp | |
#include "StdAfx.h" | |
#include "7zProperties.h" | |
#include "7zHeader.h" | |
#include "7zHandler.h" | |
// #define _MULTI_PACK | |
namespace NArchive { | |
namespace N7z { | |
struct CPropMap | |
{ | |
UInt64 FilePropID; | |
STATPROPSTG StatPROPSTG; | |
}; | |
CPropMap kPropMap[] = | |
{ | |
{ NID::kName, { NULL, kpidPath, VT_BSTR } }, | |
{ NID::kSize, { NULL, kpidSize, VT_UI8 } }, | |
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, | |
#ifdef _MULTI_PACK | |
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } }, | |
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } }, | |
{ 102, { L"Pack2", kpidPackedSize2, VT_UI8 } }, | |
{ 103, { L"Pack3", kpidPackedSize3, VT_UI8 } }, | |
{ 104, { L"Pack4", kpidPackedSize4, VT_UI8 } }, | |
#endif | |
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, | |
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } }, | |
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } }, | |
{ NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } }, | |
{ NID::kStartPos, { NULL, kpidPosition, VT_UI4 } }, | |
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } }, | |
{ NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } } | |
#ifndef _SFX | |
, | |
{ 97, { NULL,kpidEncrypted, VT_BOOL } }, | |
{ 98, { NULL,kpidMethod, VT_BSTR } }, | |
{ 99, { NULL,kpidBlock, VT_UI4 } } | |
#endif | |
}; | |
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); | |
static int FindPropInMap(UInt64 filePropID) | |
{ | |
for (int i = 0; i < kPropMapSize; i++) | |
if (kPropMap[i].FilePropID == filePropID) | |
return i; | |
return -1; | |
} | |
static void CopyOneItem(CRecordVector<UInt64> &src, | |
CRecordVector<UInt64> &dest, UInt32 item) | |
{ | |
for (int i = 0; i < src.Size(); i++) | |
if (src[i] == item) | |
{ | |
dest.Add(item); | |
src.Delete(i); | |
return; | |
} | |
} | |
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) | |
{ | |
for (int i = 0; i < src.Size(); i++) | |
if (src[i] == item) | |
{ | |
src.Delete(i); | |
return; | |
} | |
} | |
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) | |
{ | |
for (int i = 0; i < dest.Size(); i++) | |
if (dest[i] == item) | |
{ | |
dest.Delete(i); | |
break; | |
} | |
dest.Insert(0, item); | |
} | |
void CHandler::FillPopIDs() | |
{ | |
_fileInfoPopIDs.Clear(); | |
#ifdef _7Z_VOL | |
if(_volumes.Size() < 1) | |
return; | |
const CVolume &volume = _volumes.Front(); | |
const CArchiveDatabaseEx &_db = volume.Database; | |
#endif | |
CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs; | |
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); | |
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); | |
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); | |
_fileInfoPopIDs += fileInfoPopIDs; | |
#ifndef _SFX | |
_fileInfoPopIDs.Add(97); | |
_fileInfoPopIDs.Add(98); | |
_fileInfoPopIDs.Add(99); | |
#endif | |
#ifdef _MULTI_PACK | |
_fileInfoPopIDs.Add(100); | |
_fileInfoPopIDs.Add(101); | |
_fileInfoPopIDs.Add(102); | |
_fileInfoPopIDs.Add(103); | |
_fileInfoPopIDs.Add(104); | |
#endif | |
#ifndef _SFX | |
InsertToHead(_fileInfoPopIDs, NID::kMTime); | |
InsertToHead(_fileInfoPopIDs, NID::kPackInfo); | |
InsertToHead(_fileInfoPopIDs, NID::kSize); | |
InsertToHead(_fileInfoPopIDs, NID::kName); | |
#endif | |
} | |
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) | |
{ | |
*numProperties = _fileInfoPopIDs.Size(); | |
return S_OK; | |
} | |
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) | |
{ | |
if ((int)index >= _fileInfoPopIDs.Size()) | |
return E_INVALIDARG; | |
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); | |
if (indexInMap == -1) | |
return E_INVALIDARG; | |
const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG; | |
*propID = srcItem.propid; | |
*varType = srcItem.vt; | |
*name = 0; | |
return S_OK; | |
} | |
}} |