1 // MyWindows.cpp 2 3 #include "StdAfx.h" 4 5 #ifndef _WIN32 6 7 #include <stdlib.h> 8 9 #include "MyWindows.h" 10 11 static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } 12 static 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 29 typedef 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 36 BSTR 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 57 BSTR 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 74 BSTR 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 84 void SysFreeString(BSTR bstr) 85 { 86 if (bstr) 87 FreeForBSTR((CBstrSizeType *)bstr - 1); 88 } 89 90 UINT SysStringByteLen(BSTR bstr) 91 { 92 if (!bstr) 93 return 0; 94 return *((CBstrSizeType *)bstr - 1); 95 } 96 97 UINT SysStringLen(BSTR bstr) 98 { 99 if (!bstr) 100 return 0; 101 return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR); 102 } 103 104 105 HRESULT 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 113 HRESULT 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 131 LONG 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 140 DWORD GetLastError() 141 { 142 return 0; 143 } 144 145 #endif 146