1 // MyWindows.cpp
2 
3 #include "StdAfx.h"
4 
5 #ifndef _WIN32
6 
7 #include <stdlib.h>
8 
9 #include "MyWindows.h"
10 
AllocateForBSTR(size_t cb)11 static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
FreeForBSTR(void * pv)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 
SysAllocStringByteLen(LPCSTR s,UINT len)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 
SysAllocStringLen(const OLECHAR * s,UINT len)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 
SysAllocString(const OLECHAR * s)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 
SysFreeString(BSTR bstr)84 void SysFreeString(BSTR bstr)
85 {
86   if (bstr)
87     FreeForBSTR((CBstrSizeType *)bstr - 1);
88 }
89 
SysStringByteLen(BSTR bstr)90 UINT SysStringByteLen(BSTR bstr)
91 {
92   if (!bstr)
93     return 0;
94   return *((CBstrSizeType *)bstr - 1);
95 }
96 
SysStringLen(BSTR bstr)97 UINT SysStringLen(BSTR bstr)
98 {
99   if (!bstr)
100     return 0;
101   return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR);
102 }
103 
104 
VariantClear(VARIANTARG * prop)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 
VariantCopy(VARIANTARG * dest,const VARIANTARG * src)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 
CompareFileTime(const FILETIME * ft1,const FILETIME * ft2)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 
GetLastError()140 DWORD GetLastError()
141 {
142   return 0;
143 }
144 
145 #endif
146