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
11 namespace NArchive {
12 namespace N7z {
13
14 struct CPropMap
15 {
16 UInt64 FilePropID;
17 STATPROPSTG StatPROPSTG;
18 };
19
20 static 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, { 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::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
38 { NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
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
FindPropInMap(UInt64 filePropID)53 static int FindPropInMap(UInt64 filePropID)
54 {
55 for (int i = 0; i < ARRAY_SIZE(kPropMap); i++)
56 if (kPropMap[i].FilePropID == filePropID)
57 return i;
58 return -1;
59 }
60
CopyOneItem(CRecordVector<UInt64> & src,CRecordVector<UInt64> & dest,UInt32 item)61 static void CopyOneItem(CRecordVector<UInt64> &src,
62 CRecordVector<UInt64> &dest, UInt32 item)
63 {
64 FOR_VECTOR (i, src)
65 if (src[i] == item)
66 {
67 dest.Add(item);
68 src.Delete(i);
69 return;
70 }
71 }
72
RemoveOneItem(CRecordVector<UInt64> & src,UInt32 item)73 static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
74 {
75 FOR_VECTOR (i, src)
76 if (src[i] == item)
77 {
78 src.Delete(i);
79 return;
80 }
81 }
82
InsertToHead(CRecordVector<UInt64> & dest,UInt32 item)83 static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
84 {
85 FOR_VECTOR (i, dest)
86 if (dest[i] == item)
87 {
88 dest.Delete(i);
89 break;
90 }
91 dest.Insert(0, item);
92 }
93
94 #define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
95
FillPopIDs()96 void CHandler::FillPopIDs()
97 {
98 _fileInfoPopIDs.Clear();
99
100 #ifdef _7Z_VOL
101 if(_volumes.Size() < 1)
102 return;
103 const CVolume &volume = _volumes.Front();
104 const CArchiveDatabaseEx &_db = volume.Database;
105 #endif
106
107 CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
108
109 RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
110 RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
111 /*
112 RemoveOneItem(fileInfoPopIDs, NID::kParent);
113 RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
114 */
115
116 COPY_ONE_ITEM(kName);
117 COPY_ONE_ITEM(kAnti);
118 COPY_ONE_ITEM(kSize);
119 COPY_ONE_ITEM(kPackInfo);
120 COPY_ONE_ITEM(kCTime);
121 COPY_ONE_ITEM(kMTime);
122 COPY_ONE_ITEM(kATime);
123 COPY_ONE_ITEM(kWinAttrib);
124 COPY_ONE_ITEM(kCRC);
125 COPY_ONE_ITEM(kComment);
126
127 _fileInfoPopIDs += fileInfoPopIDs;
128
129 #ifndef _SFX
130 _fileInfoPopIDs.Add(97);
131 _fileInfoPopIDs.Add(98);
132 _fileInfoPopIDs.Add(99);
133 #endif
134 #ifdef _MULTI_PACK
135 _fileInfoPopIDs.Add(100);
136 _fileInfoPopIDs.Add(101);
137 _fileInfoPopIDs.Add(102);
138 _fileInfoPopIDs.Add(103);
139 _fileInfoPopIDs.Add(104);
140 #endif
141
142 #ifndef _SFX
143 InsertToHead(_fileInfoPopIDs, NID::kMTime);
144 InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
145 InsertToHead(_fileInfoPopIDs, NID::kSize);
146 InsertToHead(_fileInfoPopIDs, NID::kName);
147 #endif
148 }
149
GetNumberOfProperties(UInt32 * numProps)150 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
151 {
152 *numProps = _fileInfoPopIDs.Size();
153 return S_OK;
154 }
155
GetPropertyInfo(UInt32 index,BSTR * name,PROPID * propID,VARTYPE * varType)156 STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
157 {
158 if ((int)index >= _fileInfoPopIDs.Size())
159 return E_INVALIDARG;
160 int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
161 if (indexInMap == -1)
162 return E_INVALIDARG;
163 const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
164 *propID = srcItem.propid;
165 *varType = srcItem.vt;
166 *name = 0;
167 return S_OK;
168 }
169
170 }}
171