Home | History | Annotate | Download | only in Common
      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