1// 7zProperties.cpp
2
3#include "StdAfx.h"
4
5#include "7zProperties.h"
6#include "7zHeader.h"
7#include "7zHandler.h"
8
9// #define _MULTI_PACK
10
11namespace NArchive {
12namespace N7z {
13
14struct CPropMap
15{
16  UInt64 FilePropID;
17  STATPROPSTG StatPROPSTG;
18};
19
20CPropMap kPropMap[] =
21{
22  { NID::kName, { NULL, kpidPath, VT_BSTR } },
23  { NID::kSize, { NULL, kpidSize, VT_UI8 } },
24  { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
25
26  #ifdef _MULTI_PACK
27  { 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
28  { 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
29  { 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },
30  { 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },
31  { 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },
32  #endif
33
34  { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
35  { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
36  { NID::kATime, { NULL, kpidATime, VT_FILETIME } },
37  { NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } },
38  { NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
39
40  { NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
41
42  { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
43
44  #ifndef _SFX
45  ,
46  { 97, { NULL,kpidEncrypted, VT_BOOL } },
47  { 98, { NULL,kpidMethod, VT_BSTR } },
48  { 99, { NULL,kpidBlock, VT_UI4 } }
49  #endif
50};
51
52static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
53
54static int FindPropInMap(UInt64 filePropID)
55{
56  for (int i = 0; i < kPropMapSize; i++)
57    if (kPropMap[i].FilePropID == filePropID)
58      return i;
59  return -1;
60}
61
62static void CopyOneItem(CRecordVector<UInt64> &src,
63    CRecordVector<UInt64> &dest, UInt32 item)
64{
65  for (int i = 0; i < src.Size(); i++)
66    if (src[i] == item)
67    {
68      dest.Add(item);
69      src.Delete(i);
70      return;
71    }
72}
73
74static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
75{
76  for (int i = 0; i < src.Size(); i++)
77    if (src[i] == item)
78    {
79      src.Delete(i);
80      return;
81    }
82}
83
84static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
85{
86  for (int i = 0; i < dest.Size(); i++)
87    if (dest[i] == item)
88    {
89      dest.Delete(i);
90      break;
91    }
92  dest.Insert(0, item);
93}
94
95void CHandler::FillPopIDs()
96{
97  _fileInfoPopIDs.Clear();
98
99  #ifdef _7Z_VOL
100  if(_volumes.Size() < 1)
101    return;
102  const CVolume &volume = _volumes.Front();
103  const CArchiveDatabaseEx &_db = volume.Database;
104  #endif
105
106  CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
107
108  RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
109  RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
110
111  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
112  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
113  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
114  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
115  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
116  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
117  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
118  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
119  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
120  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
121  _fileInfoPopIDs += fileInfoPopIDs;
122
123  #ifndef _SFX
124  _fileInfoPopIDs.Add(97);
125  _fileInfoPopIDs.Add(98);
126  _fileInfoPopIDs.Add(99);
127  #endif
128  #ifdef _MULTI_PACK
129  _fileInfoPopIDs.Add(100);
130  _fileInfoPopIDs.Add(101);
131  _fileInfoPopIDs.Add(102);
132  _fileInfoPopIDs.Add(103);
133  _fileInfoPopIDs.Add(104);
134  #endif
135
136  #ifndef _SFX
137  InsertToHead(_fileInfoPopIDs, NID::kMTime);
138  InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
139  InsertToHead(_fileInfoPopIDs, NID::kSize);
140  InsertToHead(_fileInfoPopIDs, NID::kName);
141  #endif
142}
143
144STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
145{
146  *numProperties = _fileInfoPopIDs.Size();
147  return S_OK;
148}
149
150STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
151{
152  if ((int)index >= _fileInfoPopIDs.Size())
153    return E_INVALIDARG;
154  int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
155  if (indexInMap == -1)
156    return E_INVALIDARG;
157  const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
158  *propID = srcItem.propid;
159  *varType = srcItem.vt;
160  *name = 0;
161  return S_OK;
162}
163
164}}
165