1 // PropVariantConv.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../Common/IntToString.h"
6 
7 #include "Defs.h"
8 #include "PropVariantConv.h"
9 
10 #define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
11 
ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level)12 bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level) throw()
13 {
14   *s = 0;
15   FILETIME ft;
16   if (!FileTimeToLocalFileTime(&utc, &ft))
17     return false;
18 
19   SYSTEMTIME st;
20   if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
21   {
22     // win10 : that function doesn't work, if bit 63 of 64-bit FILETIME is set.
23     return false;
24   }
25 
26   {
27     unsigned val = st.wYear;
28     if (val >= 10000)
29     {
30       *s++ = (char)('0' + val / 10000);
31       val %= 10000;
32     }
33     s[3] = (char)('0' + val % 10); val /= 10;
34     s[2] = (char)('0' + val % 10); val /= 10;
35     s[1] = (char)('0' + val % 10);
36     s[0] = (char)('0' + val / 10);
37     s += 4;
38   }
39   UINT_TO_STR_2('-', st.wMonth)
40   UINT_TO_STR_2('-', st.wDay)
41 
42   if (level > kTimestampPrintLevel_DAY)
43   {
44     UINT_TO_STR_2(' ', st.wHour)
45     UINT_TO_STR_2(':', st.wMinute)
46 
47     if (level >= kTimestampPrintLevel_SEC)
48     {
49       UINT_TO_STR_2(':', st.wSecond)
50 
51       if (level > kTimestampPrintLevel_SEC)
52       {
53         *s++ = '.';
54         /*
55         {
56           unsigned val = st.wMilliseconds;
57           s[2] = (char)('0' + val % 10); val /= 10;
58           s[1] = (char)('0' + val % 10);
59           s[0] = (char)('0' + val / 10);
60           s += 3;
61         }
62         *s++ = ' ';
63         */
64 
65         {
66           unsigned numDigits = 7;
67           UInt32 val = (UInt32)((((UInt64)ft.dwHighDateTime << 32) + ft.dwLowDateTime) % 10000000);
68           for (unsigned i = numDigits; i != 0;)
69           {
70             i--;
71             s[i] = (char)('0' + val % 10); val /= 10;
72           }
73           if (numDigits > (unsigned)level)
74             numDigits = (unsigned)level;
75           s += numDigits;
76         }
77         if (level >= kTimestampPrintLevel_NTFS + 1)
78         {
79           *s++ = (char)('0' + (ns100 / 10));
80           if (level >= kTimestampPrintLevel_NTFS + 2)
81             *s++ = (char)('0' + (ns100 % 10));
82         }
83       }
84     }
85   }
86 
87   *s = 0;
88   return true;
89 }
90 
91 
ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level)92 bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
93 {
94   return ConvertUtcFileTimeToString2(utc, 0, s, level);
95 }
96 
ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level)97 bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level) throw()
98 {
99   char s[32];
100   bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level);
101   for (unsigned i = 0;; i++)
102   {
103     Byte c = (Byte)s[i];
104     dest[i] = c;
105     if (c == 0)
106       break;
107   }
108   return res;
109 }
110 
ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level)111 bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw()
112 {
113   char s[32];
114   bool res = ConvertUtcFileTimeToString(ft, s, level);
115   for (unsigned i = 0;; i++)
116   {
117     Byte c = (Byte)s[i];
118     dest[i] = c;
119     if (c == 0)
120       break;
121   }
122   return res;
123 }
124 
125 
ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest)126 void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw()
127 {
128   *dest = 0;
129   switch (prop.vt)
130   {
131     case VT_EMPTY: return;
132     case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
133     case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
134     case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
135     case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
136     case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
137     case VT_FILETIME:
138     {
139       // const unsigned prec = prop.wReserved1;
140       int level = 0;
141       /*
142       if (prec == 0)
143         level = 7;
144       else if (prec > 16 && prec <= 16 + 9)
145         level = prec - 16;
146       */
147       ConvertUtcFileTimeToString(prop.filetime, dest, level);
148       return;
149     }
150     // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
151     case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
152     case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
153     case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
154     case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
155     default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2);
156   }
157 }
158 
ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest)159 void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw()
160 {
161   *dest = 0;
162   switch (prop.vt)
163   {
164     case VT_EMPTY: return;
165     case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
166     case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
167     case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
168     case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
169     case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
170     case VT_FILETIME:
171     {
172       // const unsigned prec = prop.wReserved1;
173       int level = 0;
174       /*
175       if (prec == 0)
176         level = 7;
177       else if (prec > 16 && prec <= 16 + 9)
178         level = prec - 16;
179       */
180       ConvertUtcFileTimeToString(prop.filetime, dest, level);
181       return;
182     }
183     // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
184     case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
185     case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
186     case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
187     case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? (wchar_t)'+' : (wchar_t)'-'; dest[1] = 0; return;
188     default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
189   }
190 }
191