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 UInt32 FilePropID;
17 CStatProp StatProp;
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, { "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
CopyOneItem(CRecordVector<UInt64> & src,CRecordVector<UInt64> & dest,UInt32 item)53 static 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
RemoveOneItem(CRecordVector<UInt64> & src,UInt32 item)65 static 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
InsertToHead(CRecordVector<UInt64> & dest,UInt32 item)75 static 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
FillPopIDs()88 void 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
GetNumberOfProperties(UInt32 * numProps)143 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
144 {
145 *numProps = _fileInfoPopIDs.Size();
146 return S_OK;
147 }
148
GetPropertyInfo(UInt32 index,BSTR * name,PROPID * propID,VARTYPE * varType)149 STDMETHODIMP 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