1 // 7zProperties.cpp
2
3 #include "StdAfx.h"
4
5 #include "7zHandler.h"
6 #include "7zProperties.h"
7
8 namespace NArchive {
9 namespace N7z {
10
11 struct CPropMap
12 {
13 Byte FilePropID;
14 // CStatProp StatProp;
15 VARTYPE vt;
16 UInt32 StatPropID;
17 };
18
19 // #define STAT_PROP(name, id, vt) { name, id, vt }
20 #define STAT_PROP(name, id, vt) vt, id
21
22 #define STAT_PROP2(id, vt) STAT_PROP(NULL, id, vt)
23
24 #define k_7z_id_Encrypted 97
25 #define k_7z_id_Method 98
26 #define k_7z_id_Block 99
27
28 static const CPropMap kPropMap[] =
29 {
30 { NID::kName, STAT_PROP2(kpidPath, VT_BSTR) },
31 { NID::kSize, STAT_PROP2(kpidSize, VT_UI8) },
32 { NID::kPackInfo, STAT_PROP2(kpidPackSize, VT_UI8) },
33
34 #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
35 #define k_7z_id_PackedSize0 100
36 { k_7z_id_PackedSize0 + 0, STAT_PROP("Pack0", kpidPackedSize0, VT_UI8) },
37 { k_7z_id_PackedSize0 + 1, STAT_PROP("Pack1", kpidPackedSize1, VT_UI8) },
38 { k_7z_id_PackedSize0 + 2, STAT_PROP("Pack2", kpidPackedSize2, VT_UI8) },
39 { k_7z_id_PackedSize0 + 3, STAT_PROP("Pack3", kpidPackedSize3, VT_UI8) },
40 { k_7z_id_PackedSize0 + 4, STAT_PROP("Pack4", kpidPackedSize4, VT_UI8) },
41 #endif
42
43 { NID::kCTime, STAT_PROP2(kpidCTime, VT_FILETIME) },
44 { NID::kMTime, STAT_PROP2(kpidMTime, VT_FILETIME) },
45 { NID::kATime, STAT_PROP2(kpidATime, VT_FILETIME) },
46 { NID::kWinAttrib, STAT_PROP2(kpidAttrib, VT_UI4) },
47 { NID::kStartPos, STAT_PROP2(kpidPosition, VT_UI8) },
48
49 { NID::kCRC, STAT_PROP2(kpidCRC, VT_UI4) },
50 // { NID::kIsAux, STAT_PROP2(kpidIsAux, VT_BOOL) },
51 { NID::kAnti, STAT_PROP2(kpidIsAnti, VT_BOOL) }
52
53 #ifndef Z7_SFX
54 , { k_7z_id_Encrypted, STAT_PROP2(kpidEncrypted, VT_BOOL) }
55 , { k_7z_id_Method, STAT_PROP2(kpidMethod, VT_BSTR) }
56 , { k_7z_id_Block, STAT_PROP2(kpidBlock, VT_UI4) }
57 #endif
58 };
59
CopyOneItem(CRecordVector<UInt64> & src,CRecordVector<UInt64> & dest,const UInt32 item)60 static void CopyOneItem(CRecordVector<UInt64> &src,
61 CRecordVector<UInt64> &dest, const UInt32 item)
62 {
63 FOR_VECTOR (i, src)
64 if (src[i] == item)
65 {
66 dest.Add(item);
67 src.Delete(i);
68 return;
69 }
70 }
71
RemoveOneItem(CRecordVector<UInt64> & src,const UInt32 item)72 static void RemoveOneItem(CRecordVector<UInt64> &src, const UInt32 item)
73 {
74 FOR_VECTOR (i, src)
75 if (src[i] == item)
76 {
77 src.Delete(i);
78 return;
79 }
80 }
81
InsertToHead(CRecordVector<UInt64> & dest,const UInt32 item)82 static void InsertToHead(CRecordVector<UInt64> &dest, const UInt32 item)
83 {
84 FOR_VECTOR (i, dest)
85 if (dest[i] == item)
86 {
87 dest.Delete(i);
88 break;
89 }
90 dest.Insert(0, item);
91 }
92
93 #define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
94
FillPopIDs()95 void CHandler::FillPopIDs()
96 {
97 _fileInfoPopIDs.Clear();
98
99 #ifdef Z7_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.ArcInfo.FileInfoPopIDs;
107
108 RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
109 RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
110 /*
111 RemoveOneItem(fileInfoPopIDs, NID::kParent);
112 RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
113 */
114
115 COPY_ONE_ITEM(kName)
116 COPY_ONE_ITEM(kAnti)
117 COPY_ONE_ITEM(kSize)
118 COPY_ONE_ITEM(kPackInfo)
119 COPY_ONE_ITEM(kCTime)
120 COPY_ONE_ITEM(kMTime)
121 COPY_ONE_ITEM(kATime)
122 COPY_ONE_ITEM(kWinAttrib)
123 COPY_ONE_ITEM(kCRC)
124 COPY_ONE_ITEM(kComment)
125
126 _fileInfoPopIDs += fileInfoPopIDs;
127
128 #ifndef Z7_SFX
129 _fileInfoPopIDs.Add(k_7z_id_Encrypted);
130 _fileInfoPopIDs.Add(k_7z_id_Method);
131 _fileInfoPopIDs.Add(k_7z_id_Block);
132 #endif
133
134 #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
135 for (unsigned i = 0; i < 5; i++)
136 _fileInfoPopIDs.Add(k_7z_id_PackedSize0 + i);
137 #endif
138
139 #ifndef Z7_SFX
140 InsertToHead(_fileInfoPopIDs, NID::kMTime);
141 InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
142 InsertToHead(_fileInfoPopIDs, NID::kSize);
143 InsertToHead(_fileInfoPopIDs, NID::kName);
144 #endif
145 }
146
Z7_COM7F_IMF(CHandler::GetNumberOfProperties (UInt32 * numProps))147 Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps))
148 {
149 *numProps = _fileInfoPopIDs.Size();
150 return S_OK;
151 }
152
Z7_COM7F_IMF(CHandler::GetPropertyInfo (UInt32 index,BSTR * name,PROPID * propID,VARTYPE * varType))153 Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType))
154 {
155 if (index >= _fileInfoPopIDs.Size())
156 return E_INVALIDARG;
157 const UInt64 id = _fileInfoPopIDs[index];
158 for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPropMap); i++)
159 {
160 const CPropMap &pr = kPropMap[i];
161 if (pr.FilePropID == id)
162 {
163 *propID = pr.StatPropID;
164 *varType = pr.vt;
165 /*
166 const CStatProp &st = pr.StatProp;
167 *propID = st.PropID;
168 *varType = st.vt;
169 */
170 /*
171 if (st.lpwstrName)
172 *name = ::SysAllocString(st.lpwstrName);
173 else
174 */
175 *name = NULL;
176 return S_OK;
177 }
178 }
179 return E_INVALIDARG;
180 }
181
182 }}
183