Home | History | Annotate | Download | only in Common
      1 // PropIDUtils.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "Common/IntToString.h"
      6 
      7 #include "Windows/FileFind.h"
      8 #include "Windows/PropVariantConversions.h"
      9 
     10 #include "../../PropID.h"
     11 
     12 #include "PropIDUtils.h"
     13 
     14 using namespace NWindows;
     15 
     16 void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
     17 {
     18   for (int i = 0; i < 8; i++)
     19   {
     20     int t = value & 0xF;
     21     value >>= 4;
     22     s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
     23   }
     24   s[8] = L'\0';
     25 }
     26 
     27 static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
     28 /*
     29 0 READONLY
     30 1 HIDDEN
     31 3 SYSTEM
     32 
     33 4 DIRECTORY
     34 5 ARCHIVE
     35 6 DEVICE
     36 7 NORMAL
     37 8 TEMPORARY
     38 9 SPARSE_FILE
     39 10 REPARSE_POINT
     40 11 COMPRESSED
     41 12 OFFLINE
     42 13 NOT_CONTENT_INDEXED
     43 14 ENCRYPTED
     44 
     45 16 VIRTUAL
     46 */
     47 
     48 static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
     49 #define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
     50 
     51 UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
     52 {
     53   switch(propID)
     54   {
     55     case kpidCTime:
     56     case kpidATime:
     57     case kpidMTime:
     58     {
     59       if (prop.vt != VT_FILETIME)
     60         break;
     61       FILETIME localFileTime;
     62       if ((prop.filetime.dwHighDateTime == 0 &&
     63           prop.filetime.dwLowDateTime == 0) ||
     64           !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
     65         return UString();
     66       return ConvertFileTimeToString(localFileTime, true, full);
     67     }
     68     case kpidCRC:
     69     {
     70       if (prop.vt != VT_UI4)
     71         break;
     72       wchar_t temp[12];
     73       ConvertUInt32ToHex(prop.ulVal, temp);
     74       return temp;
     75     }
     76     case kpidAttrib:
     77     {
     78       if (prop.vt != VT_UI4)
     79         break;
     80       UInt32 a = prop.ulVal;
     81       wchar_t sz[32];
     82       int pos = 0;
     83       for (int i = 0; i < 16; i++)
     84         if (a & (1 << i) && i != 7)
     85           sz[pos++] = g_WinAttrib[i];
     86       sz[pos] = '\0';
     87       return sz;
     88     }
     89     case kpidPosixAttrib:
     90     {
     91       if (prop.vt != VT_UI4)
     92         break;
     93       UString res;
     94       UInt32 a = prop.ulVal;
     95       wchar_t temp[16];
     96 
     97       temp[0] = kPosixTypes[(a >> 12) & 0xF];
     98       for (int i = 6; i >= 0; i -= 3)
     99       {
    100         temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
    101         temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
    102         temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');
    103       }
    104       if ((a & 0x800) != 0) temp[3] = ((a & (1 << 6)) ? 's' : 'S');
    105       if ((a & 0x400) != 0) temp[6] = ((a & (1 << 3)) ? 's' : 'S');
    106       if ((a & 0x200) != 0) temp[9] = ((a & (1 << 0)) ? 't' : 'T');
    107       temp[10] = 0;
    108       res = temp;
    109 
    110       a &= ~(UInt32)0xFFFF;
    111       if (a != 0)
    112       {
    113         ConvertUInt32ToHex(a, temp);
    114         res = UString(temp) + L' ' + res;
    115       }
    116       return res;
    117     }
    118   }
    119   return ConvertPropVariantToString(prop);
    120 }
    121