Source code

Revision control

Copy as Markdown

Other Tools

// MyWindows.cpp↩
#include "StdAfx.h"
#ifndef _WIN32↩
#include <stdlib.h>↩
#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