// MyWindows.cpp #include "StdAfx.h" #ifndef _WIN32 #include #include "MyWindows.h" static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } static inline void FreeForBSTR(void *pv) { ::free(pv);} /* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string. We must select CBstrSizeType for another systems (not Win32): if (CBstrSizeType is UINT32), then we support only strings smaller than 4 GB. Win32 version always has that limitation. if (CBstrSizeType is UINT), (UINT can be 16/32/64-bit) We can support strings larger than 4 GB (if UINT is 64-bit), but sizeof(UINT) can be different in parts compiled by different compilers/settings, and we can't send such BSTR strings between such parts. */ typedef UINT32 CBstrSizeType; // typedef UINT CBstrSizeType; #define k_BstrSize_Max 0xFFFFFFFF // #define k_BstrSize_Max UINT_MAX // #define k_BstrSize_Max ((UINT)(INT)-1) BSTR SysAllocStringByteLen(LPCSTR s, UINT len) { /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end. We provide also aligned null OLECHAR at the end. */ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType))) return NULL; UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1); void *p = AllocateForBSTR(size + sizeof(CBstrSizeType)); if (!p) return NULL; *(CBstrSizeType *)p = (CBstrSizeType)len; BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); if (s) memcpy(bstr, s, len); for (; len < size; len++) ((Byte *)bstr)[len] = 0; return bstr; } BSTR SysAllocStringLen(const OLECHAR *s, UINT len) { if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR)) return NULL; UINT size = len * sizeof(OLECHAR); void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR)); if (!p) return NULL; *(CBstrSizeType *)p = (CBstrSizeType)size; BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); if (s) memcpy(bstr, s, size); bstr[len] = 0; return bstr; } BSTR SysAllocString(const OLECHAR *s) { if (!s) return 0; const OLECHAR *s2 = s; while (*s2 != 0) s2++; return SysAllocStringLen(s, (UINT)(s2 - s)); } void SysFreeString(BSTR bstr) { if (bstr) FreeForBSTR((CBstrSizeType *)bstr - 1); } UINT SysStringByteLen(BSTR bstr) { if (!bstr) return 0; return *((CBstrSizeType *)bstr - 1); } UINT SysStringLen(BSTR bstr) { if (!bstr) return 0; return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR); } HRESULT VariantClear(VARIANTARG *prop) { if (prop->vt == VT_BSTR) SysFreeString(prop->bstrVal); prop->vt = VT_EMPTY; return S_OK; } HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src) { HRESULT res = ::VariantClear(dest); if (res != S_OK) return res; if (src->vt == VT_BSTR) { dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, SysStringByteLen(src->bstrVal)); if (!dest->bstrVal) return E_OUTOFMEMORY; dest->vt = VT_BSTR; } else *dest = *src; return S_OK; } LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) { if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1; if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1; if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1; if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1; return 0; } DWORD GetLastError() { return 0; } #endif