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 12bool 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 92bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw() 93{ 94 return ConvertUtcFileTimeToString2(utc, 0, s, level); 95} 96 97bool 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 111bool 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 126void 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 159void 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