163 lines
4.1 KiB
C++
163 lines
4.1 KiB
C++
// 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, kpidPackedSize, 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::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
|
|
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
|
|
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
|
|
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
|
|
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
|
|
|
|
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
|
|
|
|
{ NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
|
|
// { 97, NULL, kpidSolid, VT_BOOL},
|
|
#ifndef _SFX
|
|
{ 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 &_database = volume.Database;
|
|
#endif
|
|
|
|
CRecordVector<UInt64> fileInfoPopIDs = _database.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::kCreationTime);
|
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
|
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
|
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
|
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
|
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
|
|
_fileInfoPopIDs += fileInfoPopIDs;
|
|
|
|
#ifndef _SFX
|
|
_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::kLastWriteTime);
|
|
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;
|
|
}
|
|
|
|
}}
|