1 /**
2  * This file has no copyright assigned and is placed in the Public Domain.
3  * This file is part of the mingw-w64 runtime package.
4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5  */
6 #ifndef _INC_COMUTIL
7 #define _INC_COMUTIL
8 
9 #include <ole2.h>
10 
11 #ifndef _COM_ASSERT
12 #define _COM_ASSERT(x) ((void)0)
13 #endif
14 
15 #define _COM_MEMCPY_S(dest,destsize,src,count) memcpy(dest,src,count)
16 
17 /* Use of wsprintf might be impossible, if strsafe.h is included. */
18 #ifndef __STDC_SECURE_LIB__
19 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) wsprintf(dest,format,arg1)
20 #elif defined(UNICODE)
21 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) swprintf_s(dest,destsize,format,arg1)
22 #else
23 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) sprintf_s(dest,destsize,format,arg1)
24 #endif
25 
26 #ifdef __cplusplus
27 
28 #pragma push_macro("new")
29 #undef new
30 
31 #ifndef WINAPI
32 #if defined(_ARM_)
33 #define WINAPI
34 #else
35 #define WINAPI __stdcall
36 #endif
37 #endif
38 
39 class _com_error;
40 
41 void WINAPI _com_issue_error(HRESULT);
42 
43 class _bstr_t;
44 class _variant_t;
45 
46 namespace _com_util {
CheckError(HRESULT hr)47   inline void CheckError(HRESULT hr) throw() {
48     if(FAILED(hr)) { _com_issue_error(hr); }
49   }
50 }
51 
52 namespace _com_util {
53   BSTR WINAPI ConvertStringToBSTR(const char *pSrc);
54   char *WINAPI ConvertBSTRToString(BSTR pSrc);
55 }
56 
57 class _bstr_t {
58 public:
59   _bstr_t() throw();
60   _bstr_t(const _bstr_t &s) throw();
61   _bstr_t(const char *s);
62   _bstr_t(const wchar_t *s);
63   _bstr_t(const _variant_t &var);
64   _bstr_t(BSTR bstr,bool fCopy);
65   ~_bstr_t() throw();
66   _bstr_t &operator=(const _bstr_t &s) throw();
67   _bstr_t &operator=(const char *s);
68   _bstr_t &operator=(const wchar_t *s);
69   _bstr_t &operator=(const _variant_t &var);
70   _bstr_t &operator+=(const _bstr_t &s);
71   _bstr_t operator+(const _bstr_t &s) const;
72   friend _bstr_t operator+(const char *s1,const _bstr_t &s2);
73   friend _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2);
74   operator const wchar_t *() const throw();
75   operator wchar_t *() const throw();
76   operator const char *() const;
77   operator char *() const;
78   bool operator!() const throw();
79   bool operator==(const _bstr_t &str) const throw();
80   bool operator!=(const _bstr_t &str) const throw();
81   bool operator<(const _bstr_t &str) const throw();
82   bool operator>(const _bstr_t &str) const throw();
83   bool operator<=(const _bstr_t &str) const throw();
84   bool operator>=(const _bstr_t &str) const throw();
85   BSTR copy(bool fCopy = true) const;
86   unsigned int length() const throw();
87   void Assign(BSTR s);
88   BSTR &GetBSTR();
89   BSTR *GetAddress();
90   void Attach(BSTR s);
91   BSTR Detach() throw();
92 private:
93   class Data_t {
94   public:
95     Data_t(const char *s);
96     Data_t(const wchar_t *s);
97     Data_t(BSTR bstr,bool fCopy);
98     Data_t(const _bstr_t &s1,const _bstr_t &s2);
99     unsigned __LONG32 AddRef() throw();
100     unsigned __LONG32 Release() throw();
101     unsigned __LONG32 RefCount() const throw();
102     operator const wchar_t *() const throw();
103     operator const char *() const;
104     const wchar_t *GetWString() const throw();
105     wchar_t *&GetWString() throw();
106     const char *GetString() const;
107     BSTR Copy() const;
108     void Assign(BSTR s);
109     void Attach(BSTR s) throw();
110     unsigned int Length() const throw();
111     int Compare(const Data_t &str) const throw();
112     void *operator new(size_t sz);
113   private:
114     BSTR m_wstr;
115     mutable char *m_str;
116     unsigned __LONG32 m_RefCount;
117     Data_t() throw();
118     Data_t(const Data_t &s) throw();
119     ~Data_t() throw();
120     void _Free() throw();
121   };
122 private:
123   Data_t *m_Data;
124 private:
125   void _AddRef() throw();
126   void _Free() throw();
127   int _Compare(const _bstr_t &str) const throw();
128 };
129 
_bstr_t()130 inline _bstr_t::_bstr_t() throw() : m_Data(NULL) { }
131 
_bstr_t(const _bstr_t & s)132 inline _bstr_t::_bstr_t(const _bstr_t &s) throw() : m_Data(s.m_Data) { _AddRef(); }
133 
_bstr_t(const char * s)134 inline _bstr_t::_bstr_t(const char *s) : m_Data(new Data_t(s)) {
135   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
136 }
137 
_bstr_t(const wchar_t * s)138 inline _bstr_t::_bstr_t(const wchar_t *s) : m_Data(new Data_t(s)) {
139   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
140 }
141 
_bstr_t(BSTR bstr,bool fCopy)142 inline _bstr_t::_bstr_t(BSTR bstr,bool fCopy) : m_Data(new Data_t(bstr,fCopy)) {
143   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
144 }
145 
~_bstr_t()146 inline _bstr_t::~_bstr_t() throw() { _Free(); }
147 
throw()148 inline _bstr_t &_bstr_t::operator=(const _bstr_t &s) throw() {
149   if(this!=&s) {
150     _Free();
151     m_Data = s.m_Data;
152     _AddRef();
153   }
154   return *this;
155 }
156 
157 inline _bstr_t &_bstr_t::operator=(const char *s) {
158   _COM_ASSERT(!s || static_cast<const char *>(*this)!=s);
159   if(!s || static_cast<const char *>(*this)!=s) {
160     _Free();
161     m_Data = new Data_t(s);
162     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
163   }
164   return *this;
165 }
166 
167 inline _bstr_t &_bstr_t::operator=(const wchar_t *s) {
168   _COM_ASSERT(!s || static_cast<const wchar_t *>(*this)!=s);
169   if(!s || static_cast<const wchar_t *>(*this)!=s) {
170     _Free();
171     m_Data = new Data_t(s);
172     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
173   }
174   return *this;
175 }
176 
177 inline _bstr_t &_bstr_t::operator+=(const _bstr_t &s) {
178   Data_t *newData = new Data_t(*this,s);
179   if(!newData) { _com_issue_error(E_OUTOFMEMORY); }
180   else {
181     _Free();
182     m_Data = newData;
183   }
184   return *this;
185 }
186 
187 inline _bstr_t _bstr_t::operator+(const _bstr_t &s) const {
188   _bstr_t b = *this;
189   b += s;
190   return b;
191 }
192 
193 inline _bstr_t operator+(const char *s1,const _bstr_t &s2) {
194   _bstr_t b = s1;
195   b += s2;
196   return b;
197 }
198 
199 inline _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2) {
200   _bstr_t b = s1;
201   b += s2;
202   return b;
203 }
204 
throw()205 inline _bstr_t::operator const wchar_t *() const throw() { return (m_Data!=NULL) ? m_Data->GetWString() : NULL; }
throw()206 inline _bstr_t::operator wchar_t *() const throw() { return const_cast<wchar_t *>((m_Data!=NULL) ? m_Data->GetWString() : NULL); }
207 inline _bstr_t::operator const char *() const { return (m_Data!=NULL) ? m_Data->GetString() : NULL; }
208 inline _bstr_t::operator char *() const { return const_cast<char *>((m_Data!=NULL) ? m_Data->GetString() : NULL); }
209 inline bool _bstr_t::operator!() const throw() { return (m_Data!=NULL) ? !m_Data->GetWString() : true; }
210 inline bool _bstr_t::operator==(const _bstr_t &str) const throw() { return _Compare(str)==0; }
211 inline bool _bstr_t::operator!=(const _bstr_t &str) const throw() { return _Compare(str)!=0; }
212 inline bool _bstr_t::operator<(const _bstr_t &str) const throw() { return _Compare(str)<0; }
throw()213 inline bool _bstr_t::operator>(const _bstr_t &str) const throw() { return _Compare(str)>0; }
214 inline bool _bstr_t::operator<=(const _bstr_t &str) const throw() { return _Compare(str)<=0; }
throw()215 inline bool _bstr_t::operator>=(const _bstr_t &str) const throw() { return _Compare(str)>=0; }
copy(bool fCopy)216 inline BSTR _bstr_t::copy(bool fCopy) const { return (m_Data!=NULL) ? (fCopy ? m_Data->Copy() : m_Data->GetWString()) : NULL; }
length()217 inline unsigned int _bstr_t::length() const throw() { return (m_Data!=NULL) ? m_Data->Length() : 0; }
Assign(BSTR s)218 inline void _bstr_t::Assign(BSTR s) {
219   _COM_ASSERT(!s || !m_Data || m_Data->GetWString()!=s);
220   if(!s || !m_Data || m_Data->GetWString()!=s) {
221     _Free();
222     m_Data = new Data_t(s,TRUE);
223     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
224   }
225 }
226 
GetBSTR()227 inline BSTR &_bstr_t::GetBSTR() {
228   if(!m_Data) {
229     m_Data = new Data_t(0,FALSE);
230     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
231   }
232   return m_Data->GetWString();
233 }
234 
GetAddress()235 inline BSTR *_bstr_t::GetAddress() {
236   Attach(0);
237   return &m_Data->GetWString();
238 }
239 
Attach(BSTR s)240 inline void _bstr_t::Attach(BSTR s) {
241   _Free();
242   m_Data = new Data_t(s,FALSE);
243   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
244 }
245 
Detach()246 inline BSTR _bstr_t::Detach() throw () {
247   _COM_ASSERT(m_Data!=NULL && m_Data->RefCount()==1);
248   if(m_Data!=NULL && m_Data->RefCount()==1) {
249     BSTR b = m_Data->GetWString();
250     m_Data->GetWString() = NULL;
251     _Free();
252     return b;
253   } else {
254     _com_issue_error(E_POINTER);
255     return NULL;
256   }
257 }
258 
_AddRef()259 inline void _bstr_t::_AddRef() throw() {
260   if(m_Data!=NULL) m_Data->AddRef();
261 }
262 
_Free()263 inline void _bstr_t::_Free() throw() {
264   if(m_Data!=NULL) {
265     m_Data->Release();
266     m_Data = NULL;
267   }
268 }
269 
_Compare(const _bstr_t & str)270 inline int _bstr_t::_Compare(const _bstr_t &str) const throw() {
271   if(m_Data==str.m_Data) return 0;
272   if(!m_Data) return -1;
273   if(!str.m_Data) return 1;
274   return m_Data->Compare(*str.m_Data);
275 }
276 
Data_t(const char * s)277 inline _bstr_t::Data_t::Data_t(const char *s) : m_str(NULL),m_RefCount(1) {
278   m_wstr = _com_util::ConvertStringToBSTR(s);
279 }
280 
Data_t(const wchar_t * s)281 inline _bstr_t::Data_t::Data_t(const wchar_t *s) : m_str(NULL),m_RefCount(1) {
282   m_wstr = ::SysAllocString(s);
283   if(!m_wstr && s!=NULL) { _com_issue_error(E_OUTOFMEMORY); }
284 }
285 
Data_t(BSTR bstr,bool fCopy)286 inline _bstr_t::Data_t::Data_t(BSTR bstr,bool fCopy) : m_str(NULL),m_RefCount(1) {
287   if(fCopy && bstr!=NULL) {
288     m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
289     if(!m_wstr) { _com_issue_error(E_OUTOFMEMORY); }
290   } else m_wstr = bstr;
291 }
292 
Data_t(const _bstr_t & s1,const _bstr_t & s2)293 inline _bstr_t::Data_t::Data_t(const _bstr_t &s1,const _bstr_t &s2) : m_str(NULL),m_RefCount(1) {
294   const unsigned int l1 = s1.length();
295   const unsigned int l2 = s2.length();
296   m_wstr = ::SysAllocStringByteLen(NULL,(l1 + l2) *sizeof(wchar_t));
297   if(!m_wstr) {
298     _com_issue_error(E_OUTOFMEMORY);
299     return;
300   }
301   const wchar_t *wstr1 = static_cast<const wchar_t *>(s1);
302   if(wstr1!=NULL) {
303     _COM_MEMCPY_S(m_wstr,(l1 + l2 + 1) *sizeof(wchar_t),wstr1,(l1 + 1) *sizeof(wchar_t));
304   }
305   const wchar_t *wstr2 = static_cast<const wchar_t *>(s2);
306   if(wstr2!=NULL) {
307     _COM_MEMCPY_S(m_wstr + l1,(l2 + 1) *sizeof(wchar_t),wstr2,(l2 + 1) *sizeof(wchar_t));
308   }
309 }
310 
AddRef()311 inline unsigned __LONG32 _bstr_t::Data_t::AddRef() throw() {
312   InterlockedIncrement(reinterpret_cast<LONG*>(&m_RefCount));
313   return m_RefCount;
314 }
315 
Release()316 inline unsigned __LONG32 _bstr_t::Data_t::Release() throw() {
317   unsigned __LONG32 cRef = InterlockedDecrement(reinterpret_cast<LONG*>(&m_RefCount));
318   if(cRef==0) delete this;
319   return cRef;
320 }
321 
RefCount()322 inline unsigned __LONG32 _bstr_t::Data_t::RefCount() const throw() { return m_RefCount; }
throw()323 inline _bstr_t::Data_t::operator const wchar_t *() const throw() { return m_wstr; }
324 inline _bstr_t::Data_t::operator const char *() const { return GetString(); }
GetWString()325 inline const wchar_t *_bstr_t::Data_t::GetWString() const throw() { return m_wstr; }
GetWString()326 inline wchar_t *&_bstr_t::Data_t::GetWString() throw() { return m_wstr; }
GetString()327 inline const char *_bstr_t::Data_t::GetString() const {
328   if(!m_str) m_str = _com_util::ConvertBSTRToString(m_wstr);
329   return m_str;
330 }
Copy()331 inline BSTR _bstr_t::Data_t::Copy() const {
332   if(m_wstr!=NULL) {
333     BSTR bstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(m_wstr),::SysStringByteLen(m_wstr));
334     if(!bstr) { _com_issue_error(E_OUTOFMEMORY); }
335     return bstr;
336   }
337   return NULL;
338 }
Assign(BSTR s)339 inline void _bstr_t::Data_t::Assign(BSTR s) {
340   _Free();
341   if(s!=NULL) {
342     m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(s),::SysStringByteLen(s));
343     m_str = 0;
344   }
345 }
Attach(BSTR s)346 inline void _bstr_t::Data_t::Attach(BSTR s) throw() {
347   _Free();
348   m_wstr = s;
349   m_str = 0;
350   m_RefCount = 1;
351 }
Length()352 inline unsigned int _bstr_t::Data_t::Length() const throw() { return m_wstr ? ::SysStringLen(m_wstr) : 0; }
Compare(const _bstr_t::Data_t & str)353 inline int _bstr_t::Data_t::Compare(const _bstr_t::Data_t &str) const throw() {
354   if(!m_wstr) return str.m_wstr ? -1 : 0;
355   if(!str.m_wstr) return 1;
356   const unsigned int l1 = ::SysStringLen(m_wstr);
357   const unsigned int l2 = ::SysStringLen(str.m_wstr);
358   unsigned int len = l1;
359   if(len>l2) len = l2;
360   BSTR bstr1 = m_wstr;
361   BSTR bstr2 = str.m_wstr;
362   while (len-->0) {
363     if(*bstr1++!=*bstr2++) return bstr1[-1] - bstr2[-1];
364   }
365   return (l1<l2) ? -1 : (l1==l2) ? 0 : 1;
366 }
367 
368 #ifdef _COM_OPERATOR_NEW_THROWS
new(size_t sz)369 inline void *_bstr_t::Data_t::operator new(size_t sz) {
370   try {
371     return ::operator new(sz);
372   } catch (...) {
373     return NULL;
374   }
375 }
376 #else
new(size_t sz)377 inline void *_bstr_t::Data_t::operator new(size_t sz) {
378   return ::operator new(sz);
379 }
380 #endif
381 
~Data_t()382 inline _bstr_t::Data_t::~Data_t() throw() { _Free(); }
_Free()383 inline void _bstr_t::Data_t::_Free() throw() {
384   if(m_wstr!=NULL) ::SysFreeString(m_wstr);
385   if(m_str!=NULL) delete [] m_str;
386 }
387 
388 class _variant_t : public ::tagVARIANT {
389 public:
390   _variant_t() throw();
391   _variant_t(const VARIANT &varSrc);
392   _variant_t(const VARIANT *pSrc);
393   _variant_t(const _variant_t &varSrc);
394   _variant_t(VARIANT &varSrc,bool fCopy);
395   _variant_t(short sSrc,VARTYPE vtSrc = VT_I2);
396   _variant_t(__LONG32 lSrc,VARTYPE vtSrc = VT_I4);
397   _variant_t(float fltSrc) throw();
398   _variant_t(double dblSrc,VARTYPE vtSrc = VT_R8);
399   _variant_t(const CY &cySrc) throw();
400   _variant_t(const _bstr_t &bstrSrc);
401   _variant_t(const wchar_t *pSrc);
402   _variant_t(const char *pSrc);
403   _variant_t(IDispatch *pSrc,bool fAddRef = true) throw();
404   _variant_t(bool boolSrc) throw();
405   _variant_t(IUnknown *pSrc,bool fAddRef = true) throw();
406   _variant_t(const DECIMAL &decSrc) throw();
407   _variant_t(BYTE bSrc) throw();
408   _variant_t(char cSrc) throw();
409   _variant_t(unsigned short usSrc) throw();
410   _variant_t(unsigned __LONG32 ulSrc) throw();
411   _variant_t(int iSrc) throw();
412   _variant_t(unsigned int uiSrc) throw();
413   __MINGW_EXTENSION _variant_t(__int64 i8Src) throw();
414   __MINGW_EXTENSION _variant_t(unsigned __int64 ui8Src) throw();
415   ~_variant_t() throw();
416   operator short() const;
417   operator __LONG32() const;
418   operator float() const;
419   operator double() const;
420   operator CY() const;
421   operator _bstr_t() const;
422   operator IDispatch*() const;
423   operator bool() const;
424   operator IUnknown*() const;
425   operator DECIMAL() const;
426   operator BYTE() const;
427   operator VARIANT() const throw();
428   operator char() const;
429   operator unsigned short() const;
430   operator unsigned __LONG32() const;
431   operator int() const;
432   operator unsigned int() const;
433   __MINGW_EXTENSION operator __int64() const;
434   __MINGW_EXTENSION operator unsigned __int64() const;
435   _variant_t &operator=(const VARIANT &varSrc);
436   _variant_t &operator=(const VARIANT *pSrc);
437   _variant_t &operator=(const _variant_t &varSrc);
438   _variant_t &operator=(short sSrc);
439   _variant_t &operator=(__LONG32 lSrc);
440   _variant_t &operator=(float fltSrc);
441   _variant_t &operator=(double dblSrc);
442   _variant_t &operator=(const CY &cySrc);
443   _variant_t &operator=(const _bstr_t &bstrSrc);
444   _variant_t &operator=(const wchar_t *pSrc);
445   _variant_t &operator=(const char *pSrc);
446   _variant_t &operator=(IDispatch *pSrc);
447   _variant_t &operator=(bool boolSrc);
448   _variant_t &operator=(IUnknown *pSrc);
449   _variant_t &operator=(const DECIMAL &decSrc);
450   _variant_t &operator=(BYTE bSrc);
451   _variant_t &operator=(char cSrc);
452   _variant_t &operator=(unsigned short usSrc);
453   _variant_t &operator=(unsigned __LONG32 ulSrc);
454   _variant_t &operator=(int iSrc);
455   _variant_t &operator=(unsigned int uiSrc);
456   __MINGW_EXTENSION _variant_t &operator=(__int64 i8Src);
457   __MINGW_EXTENSION _variant_t &operator=(unsigned __int64 ui8Src);
458   bool operator==(const VARIANT &varSrc) const throw();
459   bool operator==(const VARIANT *pSrc) const throw();
460   bool operator!=(const VARIANT &varSrc) const throw();
461   bool operator!=(const VARIANT *pSrc) const throw();
462   void Clear();
463   void Attach(VARIANT &varSrc);
464   VARIANT Detach();
465   VARIANT &GetVARIANT() throw();
466   VARIANT *GetAddress();
467   void ChangeType(VARTYPE vartype,const _variant_t *pSrc = NULL);
468   void SetString(const char *pSrc);
469 };
470 
_variant_t()471 inline _variant_t::_variant_t() throw() { ::VariantInit(this); }
_variant_t(const VARIANT & varSrc)472 inline _variant_t::_variant_t(const VARIANT &varSrc) {
473   ::VariantInit(this);
474   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc)));
475 }
_variant_t(const VARIANT * pSrc)476 inline _variant_t::_variant_t(const VARIANT *pSrc) {
477   if(!pSrc) { _com_issue_error(E_POINTER); }
478   else {
479     ::VariantInit(this);
480     _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(pSrc)));
481   }
482 }
_variant_t(const _variant_t & varSrc)483 inline _variant_t::_variant_t(const _variant_t &varSrc) {
484   ::VariantInit(this);
485   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
486 }
_variant_t(VARIANT & varSrc,bool fCopy)487 inline _variant_t::_variant_t(VARIANT &varSrc,bool fCopy) {
488   if(fCopy) {
489     ::VariantInit(this);
490     _com_util::CheckError(::VariantCopy(this,&varSrc));
491   } else {
492     _COM_MEMCPY_S(this,sizeof(varSrc),&varSrc,sizeof(varSrc));
493     V_VT(&varSrc) = VT_EMPTY;
494   }
495 }
_variant_t(short sSrc,VARTYPE vtSrc)496 inline _variant_t::_variant_t(short sSrc,VARTYPE vtSrc) {
497   if((vtSrc!=VT_I2) && (vtSrc!=VT_BOOL)) {
498     _com_issue_error(E_INVALIDARG);
499     return;
500   }
501   if(vtSrc==VT_BOOL) {
502     V_VT(this) = VT_BOOL;
503     V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
504   } else {
505     V_VT(this) = VT_I2;
506     V_I2(this) = sSrc;
507   }
508 }
_variant_t(__LONG32 lSrc,VARTYPE vtSrc)509 inline _variant_t::_variant_t(__LONG32 lSrc,VARTYPE vtSrc) {
510   if((vtSrc!=VT_I4) && (vtSrc!=VT_ERROR) && (vtSrc!=VT_BOOL)) {
511     _com_issue_error(E_INVALIDARG);
512     return;
513   }
514   if(vtSrc==VT_ERROR) {
515     V_VT(this) = VT_ERROR;
516     V_ERROR(this) = lSrc;
517   } else if(vtSrc==VT_BOOL) {
518     V_VT(this) = VT_BOOL;
519     V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
520   } else {
521     V_VT(this) = VT_I4;
522     V_I4(this) = lSrc;
523   }
524 }
_variant_t(float fltSrc)525 inline _variant_t::_variant_t(float fltSrc) throw() {
526   V_VT(this) = VT_R4;
527   V_R4(this) = fltSrc;
528 }
529 
_variant_t(double dblSrc,VARTYPE vtSrc)530 inline _variant_t::_variant_t(double dblSrc,VARTYPE vtSrc) {
531   if((vtSrc!=VT_R8) && (vtSrc!=VT_DATE)) {
532     _com_issue_error(E_INVALIDARG);
533     return;
534   }
535   if(vtSrc==VT_DATE) {
536     V_VT(this) = VT_DATE;
537     V_DATE(this) = dblSrc;
538   } else {
539     V_VT(this) = VT_R8;
540     V_R8(this) = dblSrc;
541   }
542 }
_variant_t(const CY & cySrc)543 inline _variant_t::_variant_t(const CY &cySrc) throw() {
544   V_VT(this) = VT_CY;
545   V_CY(this) = cySrc;
546 }
_variant_t(const _bstr_t & bstrSrc)547 inline _variant_t::_variant_t(const _bstr_t &bstrSrc) {
548   V_VT(this) = VT_BSTR;
549   BSTR bstr = static_cast<wchar_t *>(bstrSrc);
550   if(!bstr) V_BSTR(this) = NULL;
551   else {
552     V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
553     if(!(V_BSTR(this))) { _com_issue_error(E_OUTOFMEMORY); }
554   }
555 }
_variant_t(const wchar_t * pSrc)556 inline _variant_t::_variant_t(const wchar_t *pSrc) {
557   V_VT(this) = VT_BSTR;
558   V_BSTR(this) = ::SysAllocString(pSrc);
559   if(!(V_BSTR(this)) && pSrc!=NULL) { _com_issue_error(E_OUTOFMEMORY); }
560 }
_variant_t(const char * pSrc)561 inline _variant_t::_variant_t(const char *pSrc) {
562   V_VT(this) = VT_BSTR;
563   V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
564 }
_variant_t(IDispatch * pSrc,bool fAddRef)565 inline _variant_t::_variant_t(IDispatch *pSrc,bool fAddRef) throw() {
566   V_VT(this) = VT_DISPATCH;
567   V_DISPATCH(this) = pSrc;
568   if(fAddRef && V_DISPATCH(this)!=NULL) V_DISPATCH(this)->AddRef();
569 }
_variant_t(bool boolSrc)570 inline _variant_t::_variant_t(bool boolSrc) throw() {
571   V_VT(this) = VT_BOOL;
572   V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE);
573 }
_variant_t(IUnknown * pSrc,bool fAddRef)574 inline _variant_t::_variant_t(IUnknown *pSrc,bool fAddRef) throw() {
575   V_VT(this) = VT_UNKNOWN;
576   V_UNKNOWN(this) = pSrc;
577   if(fAddRef && V_UNKNOWN(this)!=NULL) V_UNKNOWN(this)->AddRef();
578 }
_variant_t(const DECIMAL & decSrc)579 inline _variant_t::_variant_t(const DECIMAL &decSrc) throw() {
580   V_DECIMAL(this) = decSrc;
581   V_VT(this) = VT_DECIMAL;
582 }
_variant_t(BYTE bSrc)583 inline _variant_t::_variant_t(BYTE bSrc) throw() {
584   V_VT(this) = VT_UI1;
585   V_UI1(this) = bSrc;
586 }
_variant_t(char cSrc)587 inline _variant_t::_variant_t(char cSrc) throw() {
588   V_VT(this) = VT_I1;
589   V_I1(this) = cSrc;
590 }
_variant_t(unsigned short usSrc)591 inline _variant_t::_variant_t(unsigned short usSrc) throw() {
592   V_VT(this) = VT_UI2;
593   V_UI2(this) = usSrc;
594 }
_variant_t(unsigned __LONG32 ulSrc)595 inline _variant_t::_variant_t(unsigned __LONG32 ulSrc) throw() {
596   V_VT(this) = VT_UI4;
597   V_UI4(this) = ulSrc;
598 }
_variant_t(int iSrc)599 inline _variant_t::_variant_t(int iSrc) throw() {
600   V_VT(this) = VT_INT;
601   V_INT(this) = iSrc;
602 }
_variant_t(unsigned int uiSrc)603 inline _variant_t::_variant_t(unsigned int uiSrc) throw() {
604   V_VT(this) = VT_UINT;
605   V_UINT(this) = uiSrc;
606 }
_variant_t(__int64 i8Src)607 __MINGW_EXTENSION inline _variant_t::_variant_t(__int64 i8Src) throw() {
608   V_VT(this) = VT_I8;
609   V_I8(this) = i8Src;
610 }
_variant_t(unsigned __int64 ui8Src)611 __MINGW_EXTENSION inline _variant_t::_variant_t(unsigned __int64 ui8Src) throw() {
612   V_VT(this) = VT_UI8;
613   V_UI8(this) = ui8Src;
614 }
615 inline _variant_t::operator short() const {
616   if(V_VT(this)==VT_I2) return V_I2(this);
617   _variant_t varDest;
618   varDest.ChangeType(VT_I2,this);
619   return V_I2(&varDest);
620 }
__LONG32()621 inline _variant_t::operator __LONG32() const {
622   if(V_VT(this)==VT_I4) return V_I4(this);
623   _variant_t varDest;
624   varDest.ChangeType(VT_I4,this);
625   return V_I4(&varDest);
626 }
627 
628 inline _variant_t::operator float() const {
629   if(V_VT(this)==VT_R4) return V_R4(this);
630   _variant_t varDest;
631   varDest.ChangeType(VT_R4,this);
632   return V_R4(&varDest);
633 }
634 
635 inline _variant_t::operator double() const {
636   if(V_VT(this)==VT_R8) return V_R8(this);
637   _variant_t varDest;
638   varDest.ChangeType(VT_R8,this);
639   return V_R8(&varDest);
640 }
641 
CY()642 inline _variant_t::operator CY() const {
643   if(V_VT(this)==VT_CY) return V_CY(this);
644   _variant_t varDest;
645   varDest.ChangeType(VT_CY,this);
646   return V_CY(&varDest);
647 }
648 
_bstr_t()649 inline _variant_t::operator _bstr_t() const {
650   if(V_VT(this)==VT_BSTR) return V_BSTR(this);
651   _variant_t varDest;
652   varDest.ChangeType(VT_BSTR,this);
653   return V_BSTR(&varDest);
654 }
655 
656 inline _variant_t::operator IDispatch*() const {
657   if(V_VT(this)==VT_DISPATCH) {
658     if(V_DISPATCH(this)!=NULL) V_DISPATCH(this)->AddRef();
659     return V_DISPATCH(this);
660   }
661   _variant_t varDest;
662   varDest.ChangeType(VT_DISPATCH,this);
663   if(V_DISPATCH(&varDest)!=NULL) V_DISPATCH(&varDest)->AddRef();
664   return V_DISPATCH(&varDest);
665 }
666 inline _variant_t::operator bool() const {
667   if(V_VT(this)==VT_BOOL) return V_BOOL(this) ? true : false;
668   _variant_t varDest;
669   varDest.ChangeType(VT_BOOL,this);
670   return (V_BOOL(&varDest)==VARIANT_TRUE) ? true : false;
671 }
672 
673 inline _variant_t::operator IUnknown*() const {
674   if(V_VT(this)==VT_UNKNOWN) {
675     if(V_UNKNOWN(this)!=NULL) V_UNKNOWN(this)->AddRef();
676     return V_UNKNOWN(this);
677   }
678   _variant_t varDest;
679   varDest.ChangeType(VT_UNKNOWN,this);
680   if(V_UNKNOWN(&varDest)!=NULL) V_UNKNOWN(&varDest)->AddRef();
681   return V_UNKNOWN(&varDest);
682 }
DECIMAL()683 inline _variant_t::operator DECIMAL() const {
684   if(V_VT(this)==VT_DECIMAL) return V_DECIMAL(this);
685   _variant_t varDest;
686   varDest.ChangeType(VT_DECIMAL,this);
687   return V_DECIMAL(&varDest);
688 }
BYTE()689 inline _variant_t::operator BYTE() const {
690   if(V_VT(this)==VT_UI1) return V_UI1(this);
691   _variant_t varDest;
692   varDest.ChangeType(VT_UI1,this);
693   return V_UI1(&varDest);
694 }
VARIANT()695 inline _variant_t::operator VARIANT() const throw() { return *(VARIANT*) this; }
696 inline _variant_t::operator char() const {
697   if(V_VT(this)==VT_I1) return V_I1(this);
698   _variant_t varDest;
699   varDest.ChangeType(VT_I1,this);
700   return V_I1(&varDest);
701 }
702 
703 inline _variant_t::operator unsigned short() const {
704   if(V_VT(this)==VT_UI2) return V_UI2(this);
705   _variant_t varDest;
706   varDest.ChangeType(VT_UI2,this);
707   return V_UI2(&varDest);
708 }
709 
__LONG32()710 inline _variant_t::operator unsigned __LONG32() const {
711   if(V_VT(this)==VT_UI4) return V_UI4(this);
712   _variant_t varDest;
713   varDest.ChangeType(VT_UI4,this);
714   return V_UI4(&varDest);
715 }
716 inline _variant_t::operator int() const {
717   if(V_VT(this)==VT_INT) return V_INT(this);
718   _variant_t varDest;
719   varDest.ChangeType(VT_INT,this);
720   return V_INT(&varDest);
721 }
722 inline _variant_t::operator unsigned int() const {
723   if(V_VT(this)==VT_UINT) return V_UINT(this);
724   _variant_t varDest;
725   varDest.ChangeType(VT_UINT,this);
726   return V_UINT(&varDest);
727 }
__int64()728 __MINGW_EXTENSION inline _variant_t::operator __int64() const {
729   if(V_VT(this)==VT_I8) return V_I8(this);
730   _variant_t varDest;
731   varDest.ChangeType(VT_I8,this);
732   return V_I8(&varDest);
733 }
__int64()734 __MINGW_EXTENSION inline _variant_t::operator unsigned __int64() const {
735   if(V_VT(this)==VT_UI8) return V_UI8(this);
736   _variant_t varDest;
737   varDest.ChangeType(VT_UI8,this);
738   return V_UI8(&varDest);
739 }
740 inline _variant_t &_variant_t::operator=(const VARIANT &varSrc) {
741   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc)));
742   return *this;
743 }
744 inline _variant_t &_variant_t::operator=(const VARIANT *pSrc) {
745   if(!pSrc) { _com_issue_error(E_POINTER); }
746   else { _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(pSrc))); }
747   return *this;
748 }
749 inline _variant_t &_variant_t::operator=(const _variant_t &varSrc) {
750   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
751   return *this;
752 }
753 inline _variant_t &_variant_t::operator=(short sSrc) {
754   if(V_VT(this)==VT_I2) V_I2(this) = sSrc;
755   else if(V_VT(this)==VT_BOOL) V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
756   else {
757     Clear();
758     V_VT(this) = VT_I2;
759     V_I2(this) = sSrc;
760   }
761   return *this;
762 }
763 inline _variant_t &_variant_t::operator=(__LONG32 lSrc) {
764   if(V_VT(this)==VT_I4) V_I4(this) = lSrc;
765   else if(V_VT(this)==VT_ERROR) V_ERROR(this) = lSrc;
766   else if(V_VT(this)==VT_BOOL) V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
767   else {
768     Clear();
769     V_VT(this) = VT_I4;
770     V_I4(this) = lSrc;
771   }
772   return *this;
773 }
774 inline _variant_t &_variant_t::operator=(float fltSrc) {
775   if(V_VT(this)!=VT_R4) {
776     Clear();
777     V_VT(this) = VT_R4;
778   }
779   V_R4(this) = fltSrc;
780   return *this;
781 }
782 
783 inline _variant_t &_variant_t::operator=(double dblSrc)
784 {
785   if(V_VT(this)==VT_R8) {
786     V_R8(this) = dblSrc;
787   }
788   else if(V_VT(this)==VT_DATE) {
789     V_DATE(this) = dblSrc;
790   }
791   else {
792 
793     Clear();
794 
795     V_VT(this) = VT_R8;
796     V_R8(this) = dblSrc;
797   }
798 
799   return *this;
800 }
801 
802 inline _variant_t &_variant_t::operator=(const CY &cySrc)
803 {
804   if(V_VT(this)!=VT_CY) {
805 
806     Clear();
807 
808     V_VT(this) = VT_CY;
809   }
810 
811   V_CY(this) = cySrc;
812 
813   return *this;
814 }
815 
816 inline _variant_t &_variant_t::operator=(const _bstr_t &bstrSrc)
817 {
818   _COM_ASSERT(V_VT(this)!=VT_BSTR || !((BSTR) bstrSrc) || V_BSTR(this)!=(BSTR) bstrSrc);
819 
820   Clear();
821 
822   V_VT(this) = VT_BSTR;
823 
824   if(!bstrSrc) {
825     V_BSTR(this) = NULL;
826   }
827   else {
828     BSTR bstr = static_cast<wchar_t *>(bstrSrc);
829     V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
830 
831     if(!(V_BSTR(this))) {
832       _com_issue_error(E_OUTOFMEMORY);
833     }
834   }
835 
836   return *this;
837 }
838 
839 inline _variant_t &_variant_t::operator=(const wchar_t *pSrc)
840 {
841   _COM_ASSERT(V_VT(this)!=VT_BSTR || !pSrc || V_BSTR(this)!=pSrc);
842 
843   Clear();
844 
845   V_VT(this) = VT_BSTR;
846 
847   if(!pSrc) {
848     V_BSTR(this) = NULL;
849   }
850   else {
851     V_BSTR(this) = ::SysAllocString(pSrc);
852 
853     if(!(V_BSTR(this))) {
854       _com_issue_error(E_OUTOFMEMORY);
855     }
856   }
857 
858   return *this;
859 }
860 
861 inline _variant_t &_variant_t::operator=(const char *pSrc)
862 {
863   _COM_ASSERT(V_VT(this)!=(VT_I1 | VT_BYREF) || !pSrc || V_I1REF(this)!=pSrc);
864 
865   Clear();
866 
867   V_VT(this) = VT_BSTR;
868   V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
869 
870   return *this;
871 }
872 
873 inline _variant_t &_variant_t::operator=(IDispatch *pSrc)
874 {
875   _COM_ASSERT(V_VT(this)!=VT_DISPATCH || pSrc==0 || V_DISPATCH(this)!=pSrc);
876 
877   Clear();
878 
879   V_VT(this) = VT_DISPATCH;
880   V_DISPATCH(this) = pSrc;
881 
882   if(V_DISPATCH(this)!=NULL) {
883 
884     V_DISPATCH(this)->AddRef();
885   }
886 
887   return *this;
888 }
889 
890 inline _variant_t &_variant_t::operator=(bool boolSrc)
891 {
892   if(V_VT(this)!=VT_BOOL) {
893 
894     Clear();
895 
896     V_VT(this) = VT_BOOL;
897   }
898 
899   V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE);
900 
901   return *this;
902 }
903 
904 inline _variant_t &_variant_t::operator=(IUnknown *pSrc)
905 {
906   _COM_ASSERT(V_VT(this)!=VT_UNKNOWN || !pSrc || V_UNKNOWN(this)!=pSrc);
907 
908   Clear();
909 
910   V_VT(this) = VT_UNKNOWN;
911   V_UNKNOWN(this) = pSrc;
912 
913   if(V_UNKNOWN(this)!=NULL) {
914 
915     V_UNKNOWN(this)->AddRef();
916   }
917 
918   return *this;
919 }
920 
921 inline _variant_t &_variant_t::operator=(const DECIMAL &decSrc)
922 {
923   if(V_VT(this)!=VT_DECIMAL) {
924 
925     Clear();
926   }
927 
928   V_DECIMAL(this) = decSrc;
929   V_VT(this) = VT_DECIMAL;
930 
931   return *this;
932 }
933 
934 inline _variant_t &_variant_t::operator=(BYTE bSrc)
935 {
936   if(V_VT(this)!=VT_UI1) {
937 
938     Clear();
939 
940     V_VT(this) = VT_UI1;
941   }
942 
943   V_UI1(this) = bSrc;
944 
945   return *this;
946 }
947 
948 inline _variant_t &_variant_t::operator=(char cSrc)
949 {
950   if(V_VT(this)!=VT_I1) {
951 
952     Clear();
953 
954     V_VT(this) = VT_I1;
955   }
956 
957   V_I1(this) = cSrc;
958 
959   return *this;
960 }
961 
962 inline _variant_t &_variant_t::operator=(unsigned short usSrc)
963 {
964   if(V_VT(this)!=VT_UI2) {
965 
966     Clear();
967 
968     V_VT(this) = VT_UI2;
969   }
970 
971   V_UI2(this) = usSrc;
972 
973   return *this;
974 }
975 
976 inline _variant_t &_variant_t::operator=(unsigned __LONG32 ulSrc)
977 {
978   if(V_VT(this)!=VT_UI4) {
979 
980     Clear();
981 
982     V_VT(this) = VT_UI4;
983   }
984 
985   V_UI4(this) = ulSrc;
986 
987   return *this;
988 }
989 
990 inline _variant_t &_variant_t::operator=(int iSrc)
991 {
992   if(V_VT(this)!=VT_INT) {
993 
994     Clear();
995 
996     V_VT(this) = VT_INT;
997   }
998 
999   V_INT(this) = iSrc;
1000 
1001   return *this;
1002 }
1003 
1004 inline _variant_t &_variant_t::operator=(unsigned int uiSrc)
1005 {
1006   if(V_VT(this)!=VT_UINT) {
1007 
1008     Clear();
1009 
1010     V_VT(this) = VT_UINT;
1011   }
1012 
1013   V_UINT(this) = uiSrc;
1014 
1015   return *this;
1016 }
1017 
1018 __MINGW_EXTENSION inline _variant_t &_variant_t::operator=(__int64 i8Src) {
1019   if(V_VT(this)!=VT_I8) {
1020 
1021     Clear();
1022 
1023     V_VT(this) = VT_I8;
1024   }
1025 
1026   V_I8(this) = i8Src;
1027 
1028   return *this;
1029 }
1030 
1031 __MINGW_EXTENSION inline _variant_t &_variant_t::operator=(unsigned __int64 ui8Src) {
1032   if(V_VT(this)!=VT_UI8) {
1033 
1034     Clear();
1035 
1036     V_VT(this) = VT_UI8;
1037   }
1038 
1039   V_UI8(this) = ui8Src;
1040 
1041   return *this;
1042 }
1043 
1044 inline bool _variant_t::operator==(const VARIANT &varSrc) const throw() {
1045   return *this==&varSrc;
1046 }
1047 
1048 inline bool _variant_t::operator==(const VARIANT *pSrc) const throw()
1049 {
1050   if(!pSrc) {
1051     return false;
1052   }
1053 
1054   if(this==pSrc) {
1055     return true;
1056   }
1057 
1058   if(V_VT(this)!=V_VT(pSrc)) {
1059     return false;
1060   }
1061 
1062   switch (V_VT(this)) {
1063 case VT_EMPTY:
1064 case VT_NULL:
1065   return true;
1066 
1067 case VT_I2:
1068   return V_I2(this)==V_I2(pSrc);
1069 
1070 case VT_I4:
1071   return V_I4(this)==V_I4(pSrc);
1072 
1073 case VT_R4:
1074   return V_R4(this)==V_R4(pSrc);
1075 
1076 case VT_R8:
1077   return V_R8(this)==V_R8(pSrc);
1078 
1079 case VT_CY:
1080   return memcmp(&(V_CY(this)),&(V_CY(pSrc)),sizeof(CY))==0;
1081 
1082 case VT_DATE:
1083   return V_DATE(this)==V_DATE(pSrc);
1084 
1085 case VT_BSTR:
1086   return (::SysStringByteLen(V_BSTR(this))==::SysStringByteLen(V_BSTR(pSrc))) &&
1087     (memcmp(V_BSTR(this),V_BSTR(pSrc),::SysStringByteLen(V_BSTR(this)))==0);
1088 
1089 case VT_DISPATCH:
1090   return V_DISPATCH(this)==V_DISPATCH(pSrc);
1091 
1092 case VT_ERROR:
1093   return V_ERROR(this)==V_ERROR(pSrc);
1094 
1095 case VT_BOOL:
1096   return V_BOOL(this)==V_BOOL(pSrc);
1097 
1098 case VT_UNKNOWN:
1099   return V_UNKNOWN(this)==V_UNKNOWN(pSrc);
1100 
1101 case VT_DECIMAL:
1102   return memcmp(&(V_DECIMAL(this)),&(V_DECIMAL(pSrc)),sizeof(DECIMAL))==0;
1103 
1104 case VT_UI1:
1105   return V_UI1(this)==V_UI1(pSrc);
1106 
1107 case VT_I1:
1108   return V_I1(this)==V_I1(pSrc);
1109 
1110 case VT_UI2:
1111   return V_UI2(this)==V_UI2(pSrc);
1112 
1113 case VT_UI4:
1114   return V_UI4(this)==V_UI4(pSrc);
1115 
1116 case VT_INT:
1117   return V_INT(this)==V_INT(pSrc);
1118 
1119 case VT_UINT:
1120   return V_UINT(this)==V_UINT(pSrc);
1121 
1122 case VT_I8:
1123   return V_I8(this)==V_I8(pSrc);
1124 
1125 case VT_UI8:
1126   return V_UI8(this)==V_UI8(pSrc);
1127 
1128 default:
1129   _com_issue_error(E_INVALIDARG);
1130 
1131   }
1132 
1133   return false;
1134 }
1135 
1136 inline bool _variant_t::operator!=(const VARIANT &varSrc) const throw()
1137 {
1138   return !(*this==&varSrc);
1139 }
1140 
1141 inline bool _variant_t::operator!=(const VARIANT *pSrc) const throw()
1142 {
1143   return !(*this==pSrc);
1144 }
1145 
Clear()1146 inline void _variant_t::Clear()
1147 {
1148   _com_util::CheckError(::VariantClear(this));
1149 }
1150 
Attach(VARIANT & varSrc)1151 inline void _variant_t::Attach(VARIANT &varSrc)
1152 {
1153 
1154   Clear();
1155 
1156   _COM_MEMCPY_S(this,sizeof(varSrc),&varSrc,sizeof(varSrc));
1157   V_VT(&varSrc) = VT_EMPTY;
1158 }
1159 
Detach()1160 inline VARIANT _variant_t::Detach()
1161 {
1162   VARIANT varResult = *this;
1163   V_VT(this) = VT_EMPTY;
1164 
1165   return varResult;
1166 }
1167 
GetVARIANT()1168 inline VARIANT &_variant_t::GetVARIANT() throw()
1169 {
1170   return *(VARIANT*) this;
1171 }
1172 
GetAddress()1173 inline VARIANT *_variant_t::GetAddress() {
1174   Clear();
1175   return (VARIANT*) this;
1176 }
ChangeType(VARTYPE vartype,const _variant_t * pSrc)1177 inline void _variant_t::ChangeType(VARTYPE vartype,const _variant_t *pSrc) {
1178   if(!pSrc) pSrc = this;
1179   if((this!=pSrc) || (vartype!=V_VT(this))) {
1180     _com_util::CheckError(::VariantChangeType(static_cast<VARIANT*>(this),const_cast<VARIANT*>(static_cast<const VARIANT*>(pSrc)),0,vartype));
1181   }
1182 }
SetString(const char * pSrc)1183 inline void _variant_t::SetString(const char *pSrc) { operator=(pSrc); }
~_variant_t()1184 inline _variant_t::~_variant_t() throw() { ::VariantClear(this); }
_bstr_t(const _variant_t & var)1185 inline _bstr_t::_bstr_t(const _variant_t &var) : m_Data(NULL) {
1186   if(V_VT(&var)==VT_BSTR) {
1187     *this = V_BSTR(&var);
1188     return;
1189   }
1190   _variant_t varDest;
1191   varDest.ChangeType(VT_BSTR,&var);
1192   *this = V_BSTR(&varDest);
1193 }
1194 inline _bstr_t &_bstr_t::operator=(const _variant_t &var) {
1195   if(V_VT(&var)==VT_BSTR) {
1196     *this = V_BSTR(&var);
1197     return *this;
1198   }
1199   _variant_t varDest;
1200   varDest.ChangeType(VT_BSTR,&var);
1201   *this = V_BSTR(&varDest);
1202   return *this;
1203 }
1204 
1205 extern _variant_t vtMissing;
1206 
1207 #ifndef _USE_RAW
1208 #define bstr_t _bstr_t
1209 #define variant_t _variant_t
1210 #endif
1211 
1212 #pragma pop_macro("new")
1213 
1214 /* We use _com_issue_error here, but we only provide its inline version in comdef.h,
1215  * so we need to make sure that it's included as well. */
1216 #include <comdef.h>
1217 
1218 #endif /* __cplusplus */
1219 
1220 #endif
1221