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   UInt32 FilePropID;
     17   CStatProp StatProp;
     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, { "Pack0", kpidPackedSize0, VT_UI8 } },
     28   { 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
     29   { 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
     30   { 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
     31   { 104, { "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_UI8 } },
     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 void CopyOneItem(CRecordVector<UInt64> &src,
     54     CRecordVector<UInt64> &dest, UInt32 item)
     55 {
     56   FOR_VECTOR (i, src)
     57     if (src[i] == item)
     58     {
     59       dest.Add(item);
     60       src.Delete(i);
     61       return;
     62     }
     63 }
     64 
     65 static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
     66 {
     67   FOR_VECTOR (i, src)
     68     if (src[i] == item)
     69     {
     70       src.Delete(i);
     71       return;
     72     }
     73 }
     74 
     75 static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
     76 {
     77   FOR_VECTOR (i, dest)
     78     if (dest[i] == item)
     79     {
     80       dest.Delete(i);
     81       break;
     82     }
     83   dest.Insert(0, item);
     84 }
     85 
     86 #define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
     87 
     88 void CHandler::FillPopIDs()
     89 {
     90   _fileInfoPopIDs.Clear();
     91 
     92   #ifdef _7Z_VOL
     93   if (_volumes.Size() < 1)
     94     return;
     95   const CVolume &volume = _volumes.Front();
     96   const CArchiveDatabaseEx &_db = volume.Database;
     97   #endif
     98 
     99   CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
    100 
    101   RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
    102   RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
    103   /*
    104   RemoveOneItem(fileInfoPopIDs, NID::kParent);
    105   RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
    106   */
    107 
    108   COPY_ONE_ITEM(kName);
    109   COPY_ONE_ITEM(kAnti);
    110   COPY_ONE_ITEM(kSize);
    111   COPY_ONE_ITEM(kPackInfo);
    112   COPY_ONE_ITEM(kCTime);
    113   COPY_ONE_ITEM(kMTime);
    114   COPY_ONE_ITEM(kATime);
    115   COPY_ONE_ITEM(kWinAttrib);
    116   COPY_ONE_ITEM(kCRC);
    117   COPY_ONE_ITEM(kComment);
    118 
    119   _fileInfoPopIDs += fileInfoPopIDs;
    120 
    121   #ifndef _SFX
    122   _fileInfoPopIDs.Add(97);
    123   _fileInfoPopIDs.Add(98);
    124   _fileInfoPopIDs.Add(99);
    125   #endif
    126 
    127   #ifdef _MULTI_PACK
    128   _fileInfoPopIDs.Add(100);
    129   _fileInfoPopIDs.Add(101);
    130   _fileInfoPopIDs.Add(102);
    131   _fileInfoPopIDs.Add(103);
    132   _fileInfoPopIDs.Add(104);
    133   #endif
    134 
    135   #ifndef _SFX
    136   InsertToHead(_fileInfoPopIDs, NID::kMTime);
    137   InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
    138   InsertToHead(_fileInfoPopIDs, NID::kSize);
    139   InsertToHead(_fileInfoPopIDs, NID::kName);
    140   #endif
    141 }
    142 
    143 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
    144 {
    145   *numProps = _fileInfoPopIDs.Size();
    146   return S_OK;
    147 }
    148 
    149 STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
    150 {
    151   if (index >= _fileInfoPopIDs.Size())
    152     return E_INVALIDARG;
    153   UInt64 id = _fileInfoPopIDs[index];
    154   for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
    155   {
    156     const CPropMap &pr = kPropMap[i];
    157     if (pr.FilePropID == id)
    158     {
    159       const CStatProp &st = pr.StatProp;
    160       *propID = st.PropID;
    161       *varType = st.vt;
    162       /*
    163       if (st.lpwstrName)
    164         *name = ::SysAllocString(st.lpwstrName);
    165       else
    166       */
    167         *name = NULL;
    168       return S_OK;
    169     }
    170   }
    171   return E_INVALIDARG;
    172 }
    173 
    174 }}
    175