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 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::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
52 static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
53
FindPropInMap(UInt64 filePropID)54 static 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
CopyOneItem(CRecordVector<UInt64> & src,CRecordVector<UInt64> & dest,UInt32 item)62 static 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
RemoveOneItem(CRecordVector<UInt64> & src,UInt32 item)74 static 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
InsertToHead(CRecordVector<UInt64> & dest,UInt32 item)84 static 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
FillPopIDs()95 void 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
GetNumberOfProperties(UInt32 * numProperties)144 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
145 {
146 *numProperties = _fileInfoPopIDs.Size();
147 return S_OK;
148 }
149
GetPropertyInfo(UInt32 index,BSTR * name,PROPID * propID,VARTYPE * varType)150 STDMETHODIMP 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