Home | History | Annotate | Download | only in 7z
      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 
     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 
     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 
     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 
     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 
     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 
    144 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
    145 {
    146   *numProperties = _fileInfoPopIDs.Size();
    147   return S_OK;
    148 }
    149 
    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