1370b324cSopenharmony_ci// MyWindows.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#ifndef _WIN32 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include <stdlib.h> 8370b324cSopenharmony_ci#include <time.h> 9370b324cSopenharmony_ci#ifdef __GNUC__ 10370b324cSopenharmony_ci#include <sys/time.h> 11370b324cSopenharmony_ci#endif 12370b324cSopenharmony_ci 13370b324cSopenharmony_ci#include "MyWindows.h" 14370b324cSopenharmony_ci 15370b324cSopenharmony_cistatic inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } 16370b324cSopenharmony_cistatic inline void FreeForBSTR(void *pv) { ::free(pv);} 17370b324cSopenharmony_ci 18370b324cSopenharmony_ci/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string. 19370b324cSopenharmony_ci We must select CBstrSizeType for another systems (not Win32): 20370b324cSopenharmony_ci 21370b324cSopenharmony_ci if (CBstrSizeType is UINT32), 22370b324cSopenharmony_ci then we support only strings smaller than 4 GB. 23370b324cSopenharmony_ci Win32 version always has that limitation. 24370b324cSopenharmony_ci 25370b324cSopenharmony_ci if (CBstrSizeType is UINT), 26370b324cSopenharmony_ci (UINT can be 16/32/64-bit) 27370b324cSopenharmony_ci We can support strings larger than 4 GB (if UINT is 64-bit), 28370b324cSopenharmony_ci but sizeof(UINT) can be different in parts compiled by 29370b324cSopenharmony_ci different compilers/settings, 30370b324cSopenharmony_ci and we can't send such BSTR strings between such parts. 31370b324cSopenharmony_ci*/ 32370b324cSopenharmony_ci 33370b324cSopenharmony_citypedef UINT32 CBstrSizeType; 34370b324cSopenharmony_ci// typedef UINT CBstrSizeType; 35370b324cSopenharmony_ci 36370b324cSopenharmony_ci#define k_BstrSize_Max 0xFFFFFFFF 37370b324cSopenharmony_ci// #define k_BstrSize_Max UINT_MAX 38370b324cSopenharmony_ci// #define k_BstrSize_Max ((UINT)(INT)-1) 39370b324cSopenharmony_ci 40370b324cSopenharmony_ciBSTR SysAllocStringByteLen(LPCSTR s, UINT len) 41370b324cSopenharmony_ci{ 42370b324cSopenharmony_ci /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end. 43370b324cSopenharmony_ci We provide also aligned null OLECHAR at the end. */ 44370b324cSopenharmony_ci 45370b324cSopenharmony_ci if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType))) 46370b324cSopenharmony_ci return NULL; 47370b324cSopenharmony_ci 48370b324cSopenharmony_ci UINT size = (len + (UINT)sizeof(OLECHAR) + (UINT)sizeof(OLECHAR) - 1) & ~((UINT)sizeof(OLECHAR) - 1); 49370b324cSopenharmony_ci void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType)); 50370b324cSopenharmony_ci if (!p) 51370b324cSopenharmony_ci return NULL; 52370b324cSopenharmony_ci *(CBstrSizeType *)p = (CBstrSizeType)len; 53370b324cSopenharmony_ci BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); 54370b324cSopenharmony_ci if (s) 55370b324cSopenharmony_ci memcpy(bstr, s, len); 56370b324cSopenharmony_ci for (; len < size; len++) 57370b324cSopenharmony_ci ((Byte *)bstr)[len] = 0; 58370b324cSopenharmony_ci return bstr; 59370b324cSopenharmony_ci} 60370b324cSopenharmony_ci 61370b324cSopenharmony_ciBSTR SysAllocStringLen(const OLECHAR *s, UINT len) 62370b324cSopenharmony_ci{ 63370b324cSopenharmony_ci if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType)) / (UINT)sizeof(OLECHAR)) 64370b324cSopenharmony_ci return NULL; 65370b324cSopenharmony_ci 66370b324cSopenharmony_ci UINT size = len * (UINT)sizeof(OLECHAR); 67370b324cSopenharmony_ci void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType) + (UINT)sizeof(OLECHAR)); 68370b324cSopenharmony_ci if (!p) 69370b324cSopenharmony_ci return NULL; 70370b324cSopenharmony_ci *(CBstrSizeType *)p = (CBstrSizeType)size; 71370b324cSopenharmony_ci BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); 72370b324cSopenharmony_ci if (s) 73370b324cSopenharmony_ci memcpy(bstr, s, size); 74370b324cSopenharmony_ci bstr[len] = 0; 75370b324cSopenharmony_ci return bstr; 76370b324cSopenharmony_ci} 77370b324cSopenharmony_ci 78370b324cSopenharmony_ciBSTR SysAllocString(const OLECHAR *s) 79370b324cSopenharmony_ci{ 80370b324cSopenharmony_ci if (!s) 81370b324cSopenharmony_ci return NULL; 82370b324cSopenharmony_ci const OLECHAR *s2 = s; 83370b324cSopenharmony_ci while (*s2 != 0) 84370b324cSopenharmony_ci s2++; 85370b324cSopenharmony_ci return SysAllocStringLen(s, (UINT)(s2 - s)); 86370b324cSopenharmony_ci} 87370b324cSopenharmony_ci 88370b324cSopenharmony_civoid SysFreeString(BSTR bstr) 89370b324cSopenharmony_ci{ 90370b324cSopenharmony_ci if (bstr) 91370b324cSopenharmony_ci FreeForBSTR((CBstrSizeType *)bstr - 1); 92370b324cSopenharmony_ci} 93370b324cSopenharmony_ci 94370b324cSopenharmony_ciUINT SysStringByteLen(BSTR bstr) 95370b324cSopenharmony_ci{ 96370b324cSopenharmony_ci if (!bstr) 97370b324cSopenharmony_ci return 0; 98370b324cSopenharmony_ci return *((CBstrSizeType *)bstr - 1); 99370b324cSopenharmony_ci} 100370b324cSopenharmony_ci 101370b324cSopenharmony_ciUINT SysStringLen(BSTR bstr) 102370b324cSopenharmony_ci{ 103370b324cSopenharmony_ci if (!bstr) 104370b324cSopenharmony_ci return 0; 105370b324cSopenharmony_ci return *((CBstrSizeType *)bstr - 1) / (UINT)sizeof(OLECHAR); 106370b324cSopenharmony_ci} 107370b324cSopenharmony_ci 108370b324cSopenharmony_ci 109370b324cSopenharmony_ciHRESULT VariantClear(VARIANTARG *prop) 110370b324cSopenharmony_ci{ 111370b324cSopenharmony_ci if (prop->vt == VT_BSTR) 112370b324cSopenharmony_ci SysFreeString(prop->bstrVal); 113370b324cSopenharmony_ci prop->vt = VT_EMPTY; 114370b324cSopenharmony_ci return S_OK; 115370b324cSopenharmony_ci} 116370b324cSopenharmony_ci 117370b324cSopenharmony_ciHRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src) 118370b324cSopenharmony_ci{ 119370b324cSopenharmony_ci HRESULT res = ::VariantClear(dest); 120370b324cSopenharmony_ci if (res != S_OK) 121370b324cSopenharmony_ci return res; 122370b324cSopenharmony_ci if (src->vt == VT_BSTR) 123370b324cSopenharmony_ci { 124370b324cSopenharmony_ci dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, 125370b324cSopenharmony_ci SysStringByteLen(src->bstrVal)); 126370b324cSopenharmony_ci if (!dest->bstrVal) 127370b324cSopenharmony_ci return E_OUTOFMEMORY; 128370b324cSopenharmony_ci dest->vt = VT_BSTR; 129370b324cSopenharmony_ci } 130370b324cSopenharmony_ci else 131370b324cSopenharmony_ci *dest = *src; 132370b324cSopenharmony_ci return S_OK; 133370b324cSopenharmony_ci} 134370b324cSopenharmony_ci 135370b324cSopenharmony_ciLONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) 136370b324cSopenharmony_ci{ 137370b324cSopenharmony_ci if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1; 138370b324cSopenharmony_ci if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1; 139370b324cSopenharmony_ci if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1; 140370b324cSopenharmony_ci if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1; 141370b324cSopenharmony_ci return 0; 142370b324cSopenharmony_ci} 143370b324cSopenharmony_ci 144370b324cSopenharmony_ciDWORD GetLastError() 145370b324cSopenharmony_ci{ 146370b324cSopenharmony_ci return (DWORD)errno; 147370b324cSopenharmony_ci} 148370b324cSopenharmony_ci 149370b324cSopenharmony_civoid SetLastError(DWORD dw) 150370b324cSopenharmony_ci{ 151370b324cSopenharmony_ci errno = (int)dw; 152370b324cSopenharmony_ci} 153370b324cSopenharmony_ci 154370b324cSopenharmony_ci 155370b324cSopenharmony_cistatic LONG TIME_GetBias() 156370b324cSopenharmony_ci{ 157370b324cSopenharmony_ci time_t utc = time(NULL); 158370b324cSopenharmony_ci struct tm *ptm = localtime(&utc); 159370b324cSopenharmony_ci int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ 160370b324cSopenharmony_ci ptm = gmtime(&utc); 161370b324cSopenharmony_ci ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */ 162370b324cSopenharmony_ci LONG bias = (int)(mktime(ptm)-utc); 163370b324cSopenharmony_ci return bias; 164370b324cSopenharmony_ci} 165370b324cSopenharmony_ci 166370b324cSopenharmony_ci#define TICKS_PER_SEC 10000000 167370b324cSopenharmony_ci/* 168370b324cSopenharmony_ci#define SECS_PER_DAY (24 * 60 * 60) 169370b324cSopenharmony_ci#define SECS_1601_TO_1970 ((369 * 365 + 89) * (UInt64)SECS_PER_DAY) 170370b324cSopenharmony_ci#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKS_PER_SEC) 171370b324cSopenharmony_ci*/ 172370b324cSopenharmony_ci 173370b324cSopenharmony_ci#define GET_TIME_64(pft) ((pft)->dwLowDateTime | ((UInt64)(pft)->dwHighDateTime << 32)) 174370b324cSopenharmony_ci 175370b324cSopenharmony_ci#define SET_FILETIME(ft, v64) \ 176370b324cSopenharmony_ci (ft)->dwLowDateTime = (DWORD)v64; \ 177370b324cSopenharmony_ci (ft)->dwHighDateTime = (DWORD)(v64 >> 32); 178370b324cSopenharmony_ci 179370b324cSopenharmony_ci 180370b324cSopenharmony_ciBOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime) 181370b324cSopenharmony_ci{ 182370b324cSopenharmony_ci UInt64 v = GET_TIME_64(fileTime); 183370b324cSopenharmony_ci v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC); 184370b324cSopenharmony_ci SET_FILETIME(localFileTime, v) 185370b324cSopenharmony_ci return TRUE; 186370b324cSopenharmony_ci} 187370b324cSopenharmony_ci 188370b324cSopenharmony_ciBOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime) 189370b324cSopenharmony_ci{ 190370b324cSopenharmony_ci UInt64 v = GET_TIME_64(localFileTime); 191370b324cSopenharmony_ci v = (UInt64)((Int64)v + (Int64)TIME_GetBias() * TICKS_PER_SEC); 192370b324cSopenharmony_ci SET_FILETIME(fileTime, v) 193370b324cSopenharmony_ci return TRUE; 194370b324cSopenharmony_ci} 195370b324cSopenharmony_ci 196370b324cSopenharmony_ci/* 197370b324cSopenharmony_ciVOID WINAPI GetSystemTimeAsFileTime(FILETIME *ft) 198370b324cSopenharmony_ci{ 199370b324cSopenharmony_ci UInt64 t = 0; 200370b324cSopenharmony_ci timeval tv; 201370b324cSopenharmony_ci if (gettimeofday(&tv, NULL) == 0) 202370b324cSopenharmony_ci { 203370b324cSopenharmony_ci t = tv.tv_sec * (UInt64)TICKS_PER_SEC + TICKS_1601_TO_1970; 204370b324cSopenharmony_ci t += tv.tv_usec * 10; 205370b324cSopenharmony_ci } 206370b324cSopenharmony_ci SET_FILETIME(ft, t) 207370b324cSopenharmony_ci} 208370b324cSopenharmony_ci*/ 209370b324cSopenharmony_ci 210370b324cSopenharmony_ciDWORD WINAPI GetTickCount(VOID) 211370b324cSopenharmony_ci{ 212370b324cSopenharmony_ci #ifndef _WIN32 213370b324cSopenharmony_ci // gettimeofday() doesn't work in some MINGWs by unknown reason 214370b324cSopenharmony_ci timeval tv; 215370b324cSopenharmony_ci if (gettimeofday(&tv, NULL) == 0) 216370b324cSopenharmony_ci { 217370b324cSopenharmony_ci // tv_sec and tv_usec are (long) 218370b324cSopenharmony_ci return (DWORD)((UInt64)(Int64)tv.tv_sec * (UInt64)1000 + (UInt64)(Int64)tv.tv_usec / 1000); 219370b324cSopenharmony_ci } 220370b324cSopenharmony_ci #endif 221370b324cSopenharmony_ci return (DWORD)time(NULL) * 1000; 222370b324cSopenharmony_ci} 223370b324cSopenharmony_ci 224370b324cSopenharmony_ci 225370b324cSopenharmony_ci#define PERIOD_4 (4 * 365 + 1) 226370b324cSopenharmony_ci#define PERIOD_100 (PERIOD_4 * 25 - 1) 227370b324cSopenharmony_ci#define PERIOD_400 (PERIOD_100 * 4 + 1) 228370b324cSopenharmony_ci 229370b324cSopenharmony_ciBOOL WINAPI FileTimeToSystemTime(const FILETIME *ft, SYSTEMTIME *st) 230370b324cSopenharmony_ci{ 231370b324cSopenharmony_ci UInt32 v; 232370b324cSopenharmony_ci UInt64 v64 = GET_TIME_64(ft); 233370b324cSopenharmony_ci v64 /= 10000; 234370b324cSopenharmony_ci st->wMilliseconds = (WORD)(v64 % 1000); v64 /= 1000; 235370b324cSopenharmony_ci st->wSecond = (WORD)(v64 % 60); v64 /= 60; 236370b324cSopenharmony_ci st->wMinute = (WORD)(v64 % 60); v64 /= 60; 237370b324cSopenharmony_ci v = (UInt32)v64; 238370b324cSopenharmony_ci st->wHour = (WORD)(v % 24); v /= 24; 239370b324cSopenharmony_ci 240370b324cSopenharmony_ci // 1601-01-01 was Monday 241370b324cSopenharmony_ci st->wDayOfWeek = (WORD)((v + 1) % 7); 242370b324cSopenharmony_ci 243370b324cSopenharmony_ci UInt32 leaps, year, day, mon; 244370b324cSopenharmony_ci leaps = (3 * ((4 * v + (365 - 31 - 28) * 4 + 3) / PERIOD_400) + 3) / 4; 245370b324cSopenharmony_ci v += 28188 + leaps; 246370b324cSopenharmony_ci // leaps - the number of exceptions from PERIOD_4 rules starting from 1600-03-01 247370b324cSopenharmony_ci // (1959 / 64) - converts day from 03-01 to month 248370b324cSopenharmony_ci year = (20 * v - 2442) / (5 * PERIOD_4); 249370b324cSopenharmony_ci day = v - (year * PERIOD_4) / 4; 250370b324cSopenharmony_ci mon = (64 * day) / 1959; 251370b324cSopenharmony_ci st->wDay = (WORD)(day - (1959 * mon) / 64); 252370b324cSopenharmony_ci mon -= 1; 253370b324cSopenharmony_ci year += 1524; 254370b324cSopenharmony_ci if (mon > 12) 255370b324cSopenharmony_ci { 256370b324cSopenharmony_ci mon -= 12; 257370b324cSopenharmony_ci year++; 258370b324cSopenharmony_ci } 259370b324cSopenharmony_ci st->wMonth = (WORD)mon; 260370b324cSopenharmony_ci st->wYear = (WORD)year; 261370b324cSopenharmony_ci 262370b324cSopenharmony_ci /* 263370b324cSopenharmony_ci unsigned year, mon; 264370b324cSopenharmony_ci unsigned char ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 265370b324cSopenharmony_ci unsigned t; 266370b324cSopenharmony_ci 267370b324cSopenharmony_ci year = (WORD)(1601 + v / PERIOD_400 * 400); 268370b324cSopenharmony_ci v %= PERIOD_400; 269370b324cSopenharmony_ci 270370b324cSopenharmony_ci t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100; 271370b324cSopenharmony_ci t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4; 272370b324cSopenharmony_ci t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365; 273370b324cSopenharmony_ci 274370b324cSopenharmony_ci st->wYear = (WORD)year; 275370b324cSopenharmony_ci 276370b324cSopenharmony_ci if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) 277370b324cSopenharmony_ci ms[1] = 29; 278370b324cSopenharmony_ci for (mon = 0;; mon++) 279370b324cSopenharmony_ci { 280370b324cSopenharmony_ci unsigned d = ms[mon]; 281370b324cSopenharmony_ci if (v < d) 282370b324cSopenharmony_ci break; 283370b324cSopenharmony_ci v -= d; 284370b324cSopenharmony_ci } 285370b324cSopenharmony_ci st->wDay = (WORD)(v + 1); 286370b324cSopenharmony_ci st->wMonth = (WORD)(mon + 1); 287370b324cSopenharmony_ci */ 288370b324cSopenharmony_ci 289370b324cSopenharmony_ci return TRUE; 290370b324cSopenharmony_ci} 291370b324cSopenharmony_ci 292370b324cSopenharmony_ci#endif 293