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 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 
     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 
     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 
     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 
     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 
     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 
    150 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
    151 {
    152   *numProps = _fileInfoPopIDs.Size();
    153   return S_OK;
    154 }
    155 
    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