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  UInt32 FilePropID;
17  CStatProp StatProp;
18};
19
20static const CPropMap 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, { "Pack0", kpidPackedSize0, VT_UI8 } },
28  { 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
29  { 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
30  { 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
31  { 104, { "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::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
38  { NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
39
40  { NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
41
42//  { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } },
43  { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
44
45  #ifndef _SFX
46  ,
47  { 97, { NULL, kpidEncrypted, VT_BOOL } },
48  { 98, { NULL, kpidMethod, VT_BSTR } },
49  { 99, { NULL, kpidBlock, VT_UI4 } }
50  #endif
51};
52
53static void CopyOneItem(CRecordVector<UInt64> &src,
54    CRecordVector<UInt64> &dest, UInt32 item)
55{
56  FOR_VECTOR (i, src)
57    if (src[i] == item)
58    {
59      dest.Add(item);
60      src.Delete(i);
61      return;
62    }
63}
64
65static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
66{
67  FOR_VECTOR (i, src)
68    if (src[i] == item)
69    {
70      src.Delete(i);
71      return;
72    }
73}
74
75static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
76{
77  FOR_VECTOR (i, dest)
78    if (dest[i] == item)
79    {
80      dest.Delete(i);
81      break;
82    }
83  dest.Insert(0, item);
84}
85
86#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
87
88void CHandler::FillPopIDs()
89{
90  _fileInfoPopIDs.Clear();
91
92  #ifdef _7Z_VOL
93  if (_volumes.Size() < 1)
94    return;
95  const CVolume &volume = _volumes.Front();
96  const CArchiveDatabaseEx &_db = volume.Database;
97  #endif
98
99  CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
100
101  RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
102  RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
103  /*
104  RemoveOneItem(fileInfoPopIDs, NID::kParent);
105  RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
106  */
107
108  COPY_ONE_ITEM(kName);
109  COPY_ONE_ITEM(kAnti);
110  COPY_ONE_ITEM(kSize);
111  COPY_ONE_ITEM(kPackInfo);
112  COPY_ONE_ITEM(kCTime);
113  COPY_ONE_ITEM(kMTime);
114  COPY_ONE_ITEM(kATime);
115  COPY_ONE_ITEM(kWinAttrib);
116  COPY_ONE_ITEM(kCRC);
117  COPY_ONE_ITEM(kComment);
118
119  _fileInfoPopIDs += fileInfoPopIDs;
120
121  #ifndef _SFX
122  _fileInfoPopIDs.Add(97);
123  _fileInfoPopIDs.Add(98);
124  _fileInfoPopIDs.Add(99);
125  #endif
126
127  #ifdef _MULTI_PACK
128  _fileInfoPopIDs.Add(100);
129  _fileInfoPopIDs.Add(101);
130  _fileInfoPopIDs.Add(102);
131  _fileInfoPopIDs.Add(103);
132  _fileInfoPopIDs.Add(104);
133  #endif
134
135  #ifndef _SFX
136  InsertToHead(_fileInfoPopIDs, NID::kMTime);
137  InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
138  InsertToHead(_fileInfoPopIDs, NID::kSize);
139  InsertToHead(_fileInfoPopIDs, NID::kName);
140  #endif
141}
142
143STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
144{
145  *numProps = _fileInfoPopIDs.Size();
146  return S_OK;
147}
148
149STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
150{
151  if (index >= _fileInfoPopIDs.Size())
152    return E_INVALIDARG;
153  UInt64 id = _fileInfoPopIDs[index];
154  for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
155  {
156    const CPropMap &pr = kPropMap[i];
157    if (pr.FilePropID == id)
158    {
159      const CStatProp &st = pr.StatProp;
160      *propID = st.PropID;
161      *varType = st.vt;
162      /*
163      if (st.lpwstrName)
164        *name = ::SysAllocString(st.lpwstrName);
165      else
166      */
167        *name = NULL;
168      return S_OK;
169    }
170  }
171  return E_INVALIDARG;
172}
173
174}}
175