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, kpidPackedSize, 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::kCreationTime, NULL, kpidCreationTime, VT_FILETIME}, |
|
35 { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME}, |
|
36 { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME}, |
|
37 { NID::kWinAttributes, NULL, kpidAttributes, 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 // { 97, NULL, kpidSolid, VT_BOOL}, |
|
44 #ifndef _SFX |
|
45 { 98, NULL, kpidMethod, VT_BSTR}, |
|
46 { 99, NULL, kpidBlock, VT_UI4} |
|
47 #endif |
|
48 }; |
|
49 |
|
50 static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); |
|
51 |
|
52 static int FindPropInMap(UInt64 filePropID) |
|
53 { |
|
54 for (int i = 0; i < kPropMapSize; i++) |
|
55 if (kPropMap[i].FilePropID == filePropID) |
|
56 return i; |
|
57 return -1; |
|
58 } |
|
59 |
|
60 static void CopyOneItem(CRecordVector<UInt64> &src, |
|
61 CRecordVector<UInt64> &dest, UInt32 item) |
|
62 { |
|
63 for (int i = 0; i < src.Size(); i++) |
|
64 if (src[i] == item) |
|
65 { |
|
66 dest.Add(item); |
|
67 src.Delete(i); |
|
68 return; |
|
69 } |
|
70 } |
|
71 |
|
72 static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) |
|
73 { |
|
74 for (int i = 0; i < src.Size(); i++) |
|
75 if (src[i] == item) |
|
76 { |
|
77 src.Delete(i); |
|
78 return; |
|
79 } |
|
80 } |
|
81 |
|
82 static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) |
|
83 { |
|
84 for (int i = 0; i < dest.Size(); i++) |
|
85 if (dest[i] == item) |
|
86 { |
|
87 dest.Delete(i); |
|
88 break; |
|
89 } |
|
90 dest.Insert(0, item); |
|
91 } |
|
92 |
|
93 void CHandler::FillPopIDs() |
|
94 { |
|
95 _fileInfoPopIDs.Clear(); |
|
96 |
|
97 #ifdef _7Z_VOL |
|
98 if(_volumes.Size() < 1) |
|
99 return; |
|
100 const CVolume &volume = _volumes.Front(); |
|
101 const CArchiveDatabaseEx &_database = volume.Database; |
|
102 #endif |
|
103 |
|
104 CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs; |
|
105 |
|
106 RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); |
|
107 RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); |
|
108 |
|
109 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName); |
|
110 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); |
|
111 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); |
|
112 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); |
|
113 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime); |
|
114 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime); |
|
115 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime); |
|
116 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); |
|
117 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); |
|
118 CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); |
|
119 _fileInfoPopIDs += fileInfoPopIDs; |
|
120 |
|
121 #ifndef _SFX |
|
122 _fileInfoPopIDs.Add(98); |
|
123 _fileInfoPopIDs.Add(99); |
|
124 #endif |
|
125 #ifdef _MULTI_PACK |
|
126 _fileInfoPopIDs.Add(100); |
|
127 _fileInfoPopIDs.Add(101); |
|
128 _fileInfoPopIDs.Add(102); |
|
129 _fileInfoPopIDs.Add(103); |
|
130 _fileInfoPopIDs.Add(104); |
|
131 #endif |
|
132 |
|
133 #ifndef _SFX |
|
134 InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime); |
|
135 InsertToHead(_fileInfoPopIDs, NID::kPackInfo); |
|
136 InsertToHead(_fileInfoPopIDs, NID::kSize); |
|
137 InsertToHead(_fileInfoPopIDs, NID::kName); |
|
138 #endif |
|
139 } |
|
140 |
|
141 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) |
|
142 { |
|
143 *numProperties = _fileInfoPopIDs.Size(); |
|
144 return S_OK; |
|
145 } |
|
146 |
|
147 STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, |
|
148 BSTR *name, PROPID *propID, VARTYPE *varType) |
|
149 { |
|
150 if((int)index >= _fileInfoPopIDs.Size()) |
|
151 return E_INVALIDARG; |
|
152 int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); |
|
153 if (indexInMap == -1) |
|
154 return E_INVALIDARG; |
|
155 const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG; |
|
156 *propID = srcItem.propid; |
|
157 *varType = srcItem.vt; |
|
158 *name = 0; |
|
159 return S_OK; |
|
160 } |
|
161 |
|
162 }} |
|