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