1// MyWindows.cpp 2 3#include "StdAfx.h" 4 5#ifndef _WIN32 6 7#include <stdlib.h> 8 9#include "MyWindows.h" 10 11static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } 12static inline void FreeForBSTR(void *pv) { ::free(pv);} 13 14/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string. 15 We must select CBstrSizeType for another systems (not Win32): 16 17 if (CBstrSizeType is UINT32), 18 then we support only strings smaller than 4 GB. 19 Win32 version always has that limitation. 20 21 if (CBstrSizeType is UINT), 22 (UINT can be 16/32/64-bit) 23 We can support strings larger than 4 GB (if UINT is 64-bit), 24 but sizeof(UINT) can be different in parts compiled by 25 different compilers/settings, 26 and we can't send such BSTR strings between such parts. 27*/ 28 29typedef UINT32 CBstrSizeType; 30// typedef UINT CBstrSizeType; 31 32#define k_BstrSize_Max 0xFFFFFFFF 33// #define k_BstrSize_Max UINT_MAX 34// #define k_BstrSize_Max ((UINT)(INT)-1) 35 36BSTR SysAllocStringByteLen(LPCSTR s, UINT len) 37{ 38 /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end. 39 We provide also aligned null OLECHAR at the end. */ 40 41 if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType))) 42 return NULL; 43 44 UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1); 45 void *p = AllocateForBSTR(size + sizeof(CBstrSizeType)); 46 if (!p) 47 return NULL; 48 *(CBstrSizeType *)p = (CBstrSizeType)len; 49 BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); 50 if (s) 51 memcpy(bstr, s, len); 52 for (; len < size; len++) 53 ((Byte *)bstr)[len] = 0; 54 return bstr; 55} 56 57BSTR SysAllocStringLen(const OLECHAR *s, UINT len) 58{ 59 if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR)) 60 return NULL; 61 62 UINT size = len * sizeof(OLECHAR); 63 void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR)); 64 if (!p) 65 return NULL; 66 *(CBstrSizeType *)p = (CBstrSizeType)size; 67 BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); 68 if (s) 69 memcpy(bstr, s, size); 70 bstr[len] = 0; 71 return bstr; 72} 73 74BSTR SysAllocString(const OLECHAR *s) 75{ 76 if (!s) 77 return 0; 78 const OLECHAR *s2 = s; 79 while (*s2 != 0) 80 s2++; 81 return SysAllocStringLen(s, (UINT)(s2 - s)); 82} 83 84void SysFreeString(BSTR bstr) 85{ 86 if (bstr) 87 FreeForBSTR((CBstrSizeType *)bstr - 1); 88} 89 90UINT SysStringByteLen(BSTR bstr) 91{ 92 if (!bstr) 93 return 0; 94 return *((CBstrSizeType *)bstr - 1); 95} 96 97UINT SysStringLen(BSTR bstr) 98{ 99 if (!bstr) 100 return 0; 101 return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR); 102} 103 104 105HRESULT VariantClear(VARIANTARG *prop) 106{ 107 if (prop->vt == VT_BSTR) 108 SysFreeString(prop->bstrVal); 109 prop->vt = VT_EMPTY; 110 return S_OK; 111} 112 113HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src) 114{ 115 HRESULT res = ::VariantClear(dest); 116 if (res != S_OK) 117 return res; 118 if (src->vt == VT_BSTR) 119 { 120 dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, 121 SysStringByteLen(src->bstrVal)); 122 if (!dest->bstrVal) 123 return E_OUTOFMEMORY; 124 dest->vt = VT_BSTR; 125 } 126 else 127 *dest = *src; 128 return S_OK; 129} 130 131LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) 132{ 133 if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1; 134 if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1; 135 if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1; 136 if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1; 137 return 0; 138} 139 140DWORD GetLastError() 141{ 142 return 0; 143} 144 145#endif 146