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 11namespace NArchive { 12namespace N7z { 13 14struct CPropMap 15{ 16 UInt64 FilePropID; 17 STATPROPSTG StatPROPSTG; 18}; 19 20CPropMap 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 52static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); 53 54static 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 62static 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 74static 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 84static 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 95void 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 144STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) 145{ 146 *numProperties = _fileInfoPopIDs.Size(); 147 return S_OK; 148} 149 150STDMETHODIMP 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