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