1 /***
2 * comutil.h - Native C++ compiler COM support - BSTR, VARIANT wrappers header
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 ****/
7
8 #if _MSC_VER > 1000
9 #pragma once
10 #endif
11
12 #ifdef _M_CEE_PURE
13 #error comutil.h header cannot be included under /clr:safe or /clr:pure
14 #endif
15
16 #if !defined(_INC_COMUTIL)
17 #define _INC_COMUTIL
18
19 #include <ole2.h>
20
21 #if !defined(_COM_ASSERT)
22 # if defined(_DEBUG)
23 # include <assert.h>
24 # define _COM_ASSERT(x) assert(x)
25 # else
26 # define _COM_ASSERT(x) ((void)0)
27 # endif
28 #endif
29
30 #if !defined(_SECURE_COMPILER_COM)
31 /* use secure versions by default if not specified otherwise */
32 #define _SECURE_COMPILER_COM 1
33 #endif
34
35 #if _SECURE_COMPILER_COM && defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L
36
37 #include <stdio.h>
38
39 # define _COM_MEMCPY_S(dest, destsize, src, count) memcpy_s(dest, destsize, src, count)
40 # if defined(UNICODE)
41 #  define _COM_PRINTF_S_1(dest, destsize, format, arg1) swprintf_s(dest, destsize, format, arg1)
42 # else
43 #  define _COM_PRINTF_S_1(dest, destsize, format, arg1) sprintf_s(dest, destsize, format, arg1)
44 # endif
45
46 #else
47
48 # define _COM_MEMCPY_S(dest, destsize, src, count) memcpy(dest, src, count)
49 # define _COM_PRINTF_S_1(dest, destsize, format, arg1) wsprintf(dest, format, arg1)
50
51 #endif
52
53 #pragma warning(push)
54 #pragma warning(disable: 4290)
55 #pragma warning(disable: 4310)
56
57 #pragma push_macro("new")
58 #undef new
59
60 /* Add macros if the macros were not defined. */
61 #ifndef S_OK
62 #define S_OK                                              ((HRESULT)0L)
63 #endif
64 #ifndef INTSAFE_E_ARITHMETIC_OVERFLOW
65 #define INTSAFE_E_ARITHMETIC_OVERFLOW     ((HRESULT)-1)
66 #endif
67 #ifndef INTSAFE_UINT_MAX
68 #define INTSAFE_UINT_MAX                     0xffffffff
69 #endif
70 #ifndef FAILED
71 #define FAILED(hr) (((HRESULT)(hr)) < 0)
72 #endif
73
74 class _com_error;
75
76 void __declspec(noreturn) __stdcall _com_issue_error(HRESULT);
77
78 //////////////////////////////////////////////////////////////////////////////
79 //
80 // Forward class declarations
81 //
82 //////////////////////////////////////////////////////////////////////////////
83
84 class _bstr_t;
85 class _variant_t;
86
87 //////////////////////////////////////////////////////////////////////////////
88 //
89 // Error checking routines
90 //
91 //////////////////////////////////////////////////////////////////////////////
92
93 namespace _com_util {
94       inline void CheckError(HRESULT hr) throw(...)
95       {
96              if (FAILED(hr)) {
97                     _com_issue_error(hr);
98              }
99       }
100     static HRESULT UIntAdd(UINT uAugend, UINT uAddend, UINT *puResult)
101     {
102         if((uAugend + uAddend) < uAddend)
103         {
104             return INTSAFE_E_ARITHMETIC_OVERFLOW;
105         }
106         *puResult = uAugend + uAddend;
107         return S_OK;
108     }
109
110     static HRESULT UIntMult(UINT uMultiplicand, UINT uMultiplier, UINT *puResult)
111     {
112         ULONGLONG ull64Result = UInt32x32To64(uMultiplicand, uMultiplier);
113         if(ull64Result <= INTSAFE_UINT_MAX)
114         {
115             *puResult = (UINT)ull64Result;
116             return S_OK;
117         }
118         return INTSAFE_E_ARITHMETIC_OVERFLOW;
119     }
120 }
121
Lines 122 ... 852 are skipped.
853              m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char*>(s), ::SysStringByteLen(s));
854              m_str = 0;
855       }
856 }
857
858 inline void _bstr_t::Data_t::Attach(BSTR s) throw()
859 {
860       _Free();
861
862       m_wstr = s;
863       m_str = 0;
864       m_RefCount = 1;
865 }
866
867 // Return the length of the wrapper BSTR
868 //
869 inline unsigned int _bstr_t::Data_t::Length() const throw()
870 {
871       return m_wstr ? ::SysStringLen(m_wstr) : 0;
872 }
873
874 // Compare two wrapped BSTRs
875 //
876 inline int _bstr_t::Data_t::Compare(const _bstr_t::Data_t& str) const throw()
877 {
878       // Dont need to check for NULL here, because 
879       // SysStringLen will return 0 if you pass in NULL
880       const unsigned int l1 = ::SysStringLen(m_wstr);
881       const unsigned int l2 = ::SysStringLen(str.m_wstr);
882
883       unsigned int len = l1;
884       if (len > l2) {
885              len = l2;
886       }
887
888       BSTR bstr1 = m_wstr;
889       BSTR bstr2 = str.m_wstr;
890
891       while (len-- > 0) {
892              if (*bstr1++ != *bstr2++) {
893                     return bstr1[-1] - bstr2[-1];
894              }
895       }
896
897       return (l1 < l2) ? -1 : (l1 == l2) ? 0 : 1;
898 }
899
900 // Exception agnostic wrapper for new
901 //
902 #ifdef _COM_OPERATOR_NEW_THROWS
903 inline void* _bstr_t::Data_t::operator new(size_t sz) 
904 {
905       try {
906              return ::operator new(sz);
907       }
908       catch (...) {
909              return NULL;
910       }
911 }
912 #else // _COM_OPERATOR_NEW_THROWS
913 inline void* _bstr_t::Data_t::operator new(size_t sz) 
914 {
915       return ::operator new(sz);
916 }
917 #endif // _COM_OPERATOR_NEW_THROWS
918
919 // Destruct this object
920 //
921 inline _bstr_t::Data_t::~Data_t() throw()
922 {
923       _Free();
924 }
925
926 // Free up this object
927 //
928 inline void _bstr_t::Data_t::_Free() throw()
929 {
930       if (m_wstr != NULL) {
931              ::SysFreeString(m_wstr);
932       }
933
934       if (m_str != NULL) {
935              delete [] m_str;
936       }
937 }
938
939 //////////////////////////////////////////////////////////////////////////////
940 //
941 // Wrapper class for VARIANT
942 //
943 //////////////////////////////////////////////////////////////////////////////
944
945 /*
946  * VARENUM usage key,
947  *
948  * * [V] - may appear in a VARIANT
949  * * [T] - may appear in a TYPEDESC
950  * * [P] - may appear in an OLE property set
951  * * [S] - may appear in a Safe Array
952  * * [C] - supported by class _variant_t
953  *
954  *
955  *  VT_EMPTY                    [V]     [P]             nothing
956  *  VT_NULL                     [V]     [P]             SQL style Null
957  *  VT_I2                         [V][T][P][S][C]  2 byte signed int
958  *  VT_I4                         [V][T][P][S][C]  4 byte signed int
959  *  VT_R4                         [V][T][P][S][C]  4 byte real
960  *  VT_R8                         [V][T][P][S][C]  8 byte real
961  *  VT_CY                         [V][T][P][S][C]  currency
962  *  VT_DATE                     [V][T][P][S][C]  date
963  *  VT_BSTR                     [V][T][P][S][C]  OLE Automation string
964  *  VT_DISPATCH               [V][T][P][S][C]  IDispatch *
965  *  VT_ERROR                    [V][T]     [S][C]  SCODE
966  *  VT_BOOL                     [V][T][P][S][C]  True=-1, False=0
967  *  VT_VARIANT                [V][T][P][S]        VARIANT *
968  *  VT_UNKNOWN                [V][T]     [S][C]  IUnknown *
969  *  VT_DECIMAL                [V][T]     [S][C]  16 byte fixed point
970  *  VT_I1                              [T]                  signed char
971  *  VT_UI1                       [V][T][P][S][C]  unsigned char
972  *  VT_UI2                            [T][P]             unsigned short
973  *  VT_UI4                            [T][P]             unsigned short
974  *  VT_I8                              [T][P]             signed 64-bit int
975  *  VT_UI8                            [T][P]             unsigned 64-bit int
976  *  VT_INT                            [T]                  signed machine int
977  *  VT_UINT                          [T]                  unsigned machine int
978  *  VT_VOID                          [T]                  C style void
979  *  VT_HRESULT                     [T]                  Standard return type
980  *  VT_PTR                            [T]                  pointer type
981  *  VT_SAFEARRAY                  [T]                (use VT_ARRAY in VARIANT)
982  *  VT_CARRAY                       [T]                  C style array
983  *  VT_USERDEFINED               [T]                  user defined type
984  *  VT_LPSTR                         [T][P]             null terminated string
985  *  VT_LPWSTR                       [T][P]             wide null terminated string
986  *  VT_FILETIME                         [P]             FILETIME
987  *  VT_BLOB                               [P]             Length prefixed bytes
988  *  VT_STREAM                            [P]             Name of the stream follows
989  *  VT_STORAGE                          [P]             Name of the storage follows
990  *  VT_STREAMED_OBJECT             [P]             Stream contains an object
991  *  VT_STORED_OBJECT                [P]             Storage contains an object
992  *  VT_BLOB_OBJECT                    [P]             Blob contains an object
993  *  VT_CF                                   [P]             Clipboard format
994  *  VT_CLSID                              [P]             A Class ID
995  *  VT_VECTOR                            [P]             simple counted array
996  *  VT_ARRAY                    [V]                       SAFEARRAY*
997  *  VT_BYREF                    [V]                       void* for local use
998  */
999
1000 class _variant_t : public ::tagVARIANT {
1001 public:
1002       // Constructors
1003       //
1004       _variant_t() throw();
1005
1006       _variant_t(const VARIANT& varSrc) ;
1007       _variant_t(const VARIANT* pSrc) ;
1008       _variant_t(const _variant_t& varSrc) ;
1009
1010       _variant_t(VARIANT& varSrc, bool fCopy) ;                // Attach VARIANT if !fCopy
1011
1012       _variant_t(short sSrc, VARTYPE vtSrc = VT_I2) ;      // Creates a VT_I2, or a VT_BOOL
1013       _variant_t(long lSrc, VARTYPE vtSrc = VT_I4) ;        // Creates a VT_I4, a VT_ERROR, or a VT_BOOL
1014       _variant_t(float fltSrc) throw();                                                          // Creates a VT_R4
1015       _variant_t(double dblSrc, VARTYPE vtSrc = VT_R8) ; // Creates a VT_R8, or a VT_DATE
1016       _variant_t(const CY& cySrc) throw();                                                     // Creates a VT_CY
1017       _variant_t(const _bstr_t& bstrSrc) ;                         // Creates a VT_BSTR
1018       _variant_t(const wchar_t *pSrc) ;                              // Creates a VT_BSTR
1019       _variant_t(const char* pSrc) ;                                   // Creates a VT_BSTR
1020       _variant_t(IDispatch* pSrc, bool fAddRef = true) throw();                  // Creates a VT_DISPATCH
1021       _variant_t(bool boolSrc) throw();                                                          // Creates a VT_BOOL
1022       _variant_t(IUnknown* pSrc, bool fAddRef = true) throw();                    // Creates a VT_UNKNOWN
1023       _variant_t(const DECIMAL& decSrc) throw();                                           // Creates a VT_DECIMAL
1024       _variant_t(BYTE bSrc) throw();                                                               // Creates a VT_UI1
1025
1026       _variant_t(char cSrc) throw();                                                               // Creates a VT_I1
1027       _variant_t(unsigned short usSrc) throw();                                             // Creates a VT_UI2
1028       _variant_t(unsigned long ulSrc) throw();                                              // Creates a VT_UI4
1029       _variant_t(int iSrc) throw();                                                                 // Creates a VT_INT
1030       _variant_t(unsigned int uiSrc) throw();                                                // Creates a VT_UINT
1031 #if (_WIN32_WINNT >= 0x0501)
1032       _variant_t(__int64 i8Src) throw();                                                        // Creates a VT_I8
1033       _variant_t(unsigned __int64 ui8Src) throw();                                        // Creates a VT_UI8
1034 #endif
1035
1036       // Destructor
1037       //
1038       ~_variant_t() throw() ;
1039
1040       // Extractors
1041       //
1042       operator short() const ;                                             // Extracts a short from a VT_I2
1043       operator long() const ;                                              // Extracts a long from a VT_I4
1044       operator float() const ;                                             // Extracts a float from a VT_R4
1045       operator double() const ;                                           // Extracts a double from a VT_R8
1046       operator CY() const ;                                                  // Extracts a CY from a VT_CY
1047       operator _bstr_t() const ;                                         // Extracts a _bstr_t from a VT_BSTR
1048       operator IDispatch*() const ;                                    // Extracts a IDispatch* from a VT_DISPATCH
1049       operator bool() const ;                                              // Extracts a bool from a VT_BOOL
1050       operator IUnknown*() const ;                                      // Extracts a IUnknown* from a VT_UNKNOWN
1051       operator DECIMAL() const ;                                         // Extracts a DECIMAL from a VT_DECIMAL
1052       operator BYTE() const ;                                              // Extracts a BTYE (unsigned char) from a VT_UI1
1053       operator VARIANT() const throw();
1054
1055       operator char() const ;                                              // Extracts a char from a VT_I1
1056       operator unsigned short() const ;                              // Extracts a unsigned short from a VT_UI2
1057       operator unsigned long() const ;                               // Extracts a unsigned long from a VT_UI4
1058       operator int() const ;                                                // Extracts a int from a VT_INT
1059       operator unsigned int() const ;                                 // Extracts a unsigned int from a VT_UINT
1060 #if (_WIN32_WINNT >= 0x0501)
1061       operator __int64() const ;                                         // Extracts a __int64 from a VT_I8
1062       operator unsigned __int64() const ;                          // Extracts a unsigned __int64 from a VT_UI8
1063 #endif
1064
1065       // Assignment operations
1066       //
1067       _variant_t& operator=(const VARIANT& varSrc) ;
1068       _variant_t& operator=(const VARIANT* pSrc) ;
1069       _variant_t& operator=(const _variant_t& varSrc) ;
1070
1071       _variant_t& operator=(short sSrc) ;                          // Assign a VT_I2, or a VT_BOOL
1072       _variant_t& operator=(long lSrc) ;                            // Assign a VT_I4, a VT_ERROR or a VT_BOOL
1073       _variant_t& operator=(float fltSrc) ;                       // Assign a VT_R4
1074       _variant_t& operator=(double dblSrc) ;                     // Assign a VT_R8, or a VT_DATE
1075       _variant_t& operator=(const CY& cySrc) ;                  // Assign a VT_CY
1076       _variant_t& operator=(const _bstr_t& bstrSrc) ;      // Assign a VT_BSTR
1077       _variant_t& operator=(const wchar_t* pSrc) ;           // Assign a VT_BSTR
1078       _variant_t& operator=(const char* pSrc) ;                // Assign a VT_BSTR
1079       _variant_t& operator=(IDispatch* pSrc) ;                  // Assign a VT_DISPATCH
1080       _variant_t& operator=(bool boolSrc) ;                       // Assign a VT_BOOL
1081       _variant_t& operator=(IUnknown* pSrc) ;                    // Assign a VT_UNKNOWN
1082       _variant_t& operator=(const DECIMAL& decSrc) ;        // Assign a VT_DECIMAL
1083       _variant_t& operator=(BYTE bSrc) ;                            // Assign a VT_UI1
1084
1085       _variant_t& operator=(char cSrc) ;                            // Assign a VT_I1
1086       _variant_t& operator=(unsigned short usSrc) ;          // Assign a VT_UI2
1087       _variant_t& operator=(unsigned long ulSrc) ;           // Assign a VT_UI4
1088       _variant_t& operator=(int iSrc) ;                              // Assign a VT_INT
1089       _variant_t& operator=(unsigned int uiSrc) ;             // Assign a VT_UINT
1090 #if (_WIN32_WINNT >= 0x0501)
1091       _variant_t& operator=(__int64 i8Src) ;                     // Assign a VT_I8
1092       _variant_t& operator=(unsigned __int64 ui8Src) ;     // Assign a VT_UI8
1093 #endif
1094
1095       // Comparison operations
1096       //
1097       bool operator==(const VARIANT& varSrc) const throw();
1098       bool operator==(const VARIANT* pSrc) const throw();
1099
1100       bool operator!=(const VARIANT& varSrc) const throw();
1101       bool operator!=(const VARIANT* pSrc) const throw();
1102
1103       // Low-level operations
1104       //
1105       void Clear() ;
1106
1107       void Attach(VARIANT& varSrc) ;
1108       VARIANT Detach() ;
1109
1110       VARIANT& GetVARIANT() throw();
1111       VARIANT* GetAddress() ;
1112
1113       void ChangeType(VARTYPE vartype, const _variant_t* pSrc = NULL) ;
1114
1115       void SetString(const char* pSrc) ; // used to set ANSI string
1116 };
1117
1118 //////////////////////////////////////////////////////////////////////////////////////////
1119 //
1120 // Constructors
1121 //
1122 //////////////////////////////////////////////////////////////////////////////////////////
1123
1124 // Default constructor
1125 //
1126 inline _variant_t::_variant_t() throw()
1127 {
1128       ::VariantInit(this);
1129 }
1130
1131 // Construct a _variant_t from a const VARIANT&
1132 //
1133 inline _variant_t::_variant_t(const VARIANT& varSrc) 
1134 {
1135       ::VariantInit(this);
1136       _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(&varSrc)));
1137 }
1138
1139 // Construct a _variant_t from a const VARIANT*
1140 //
Lines 1141 ... 1345 are skipped.
1346
1347 // Construct a VT_UI1 VARIANT from a BYTE (unsigned char)
1348 //
1349 inline _variant_t::_variant_t(BYTE bSrc) throw()
1350 {
1351       V_VT(this) = VT_UI1;
1352       V_UI1(this) = bSrc;
1353 }
1354
1355 // Construct a VT_I1 VARIANT from a char 
1356 //
1357 inline _variant_t::_variant_t(char cSrc) throw() 
1358 {
1359       V_VT(this) = VT_I1;
1360       V_I1(this) = cSrc;
1361 }
1362
1363 // Construct a VT_UI2 VARIANT from a unsigned short 
1364 //
1365 inline _variant_t::_variant_t(unsigned short usSrc) throw()
1366 {
1367       V_VT(this) = VT_UI2;
1368       V_UI2(this) = usSrc;
1369 }
1370
1371 // Construct a VT_UI4 VARIANT from a unsigned long 
1372 //
1373 inline _variant_t::_variant_t(unsigned long ulSrc) throw()
1374 {
1375       V_VT(this) = VT_UI4;
1376       V_UI4(this) = ulSrc;
1377 }
1378
1379 // Construct a VT_INT VARIANT from a int 
1380 //
1381 inline _variant_t::_variant_t(int iSrc) throw()
1382 {
1383       V_VT(this) = VT_INT;
1384       V_INT(this) = iSrc;
1385 }
1386
1387 // Construct a VT_UINT VARIANT from a unsigned int 
1388 //
1389 inline _variant_t::_variant_t(unsigned int uiSrc) throw()
1390 {
1391       V_VT(this) = VT_UINT;
1392       V_UINT(this) = uiSrc;
1393 }
1394
1395 #if (_WIN32_WINNT >= 0x0501)
1396 // Construct a VT_I8 VARIANT from a __int64 
1397 //
1398 inline _variant_t::_variant_t(__int64 i8Src) throw()
1399 {
1400       V_VT(this) = VT_I8;
1401       V_I8(this) = i8Src;
1402 }
1403
1404 // Construct a VT_UI8 VARIANT from a unsigned __int64 
1405 //
1406 inline _variant_t::_variant_t(unsigned __int64 ui8Src) throw()
1407 {
1408       V_VT(this) = VT_UI8;
1409       V_UI8(this) = ui8Src;
1410 }
1411 #endif
1412
1413 //////////////////////////////////////////////////////////////////////////////////////////
1414 //
1415 // Extractors
1416 //
1417 //////////////////////////////////////////////////////////////////////////////////////////
1418
1419 // Extracts a VT_I2 into a short
1420 //
1421 inline _variant_t::operator short() const 
1422 {
1423       if (V_VT(this) == VT_I2) {
1424              return V_I2(this); 
1425       }
1426
1427       _variant_t varDest;
1428       varDest.ChangeType(VT_I2, this);
1429
1430       return V_I2(&varDest);
1431 }
1432
1433 // Extracts a VT_I4 into a long
1434 //
1435 inline _variant_t::operator long() const 
1436 {
1437       if (V_VT(this) == VT_I4) {
1438              return V_I4(this); 
1439       }
1440
1441       _variant_t varDest;
1442       varDest.ChangeType(VT_I4, this);
1443
1444       return V_I4(&varDest);
1445 }
1446
1447 // Extracts a VT_R4 into a float
1448 //
1449 inline _variant_t::operator float() const 
1450 {
1451       if (V_VT(this) == VT_R4) {
1452              return V_R4(this); 
1453       }
1454
1455       _variant_t varDest;
1456       varDest.ChangeType(VT_R4, this);
1457
1458       return V_R4(&varDest);
1459 }
1460
1461 // Extracts a VT_R8 into a double
1462 //
1463 inline _variant_t::operator double() const 
1464 {
1465       if (V_VT(this) == VT_R8) {
1466              return V_R8(this); 
1467       }
1468
1469       _variant_t varDest;
1470       varDest.ChangeType(VT_R8, this);
1471
1472       return V_R8(&varDest);
1473 }
1474
1475 // Extracts a VT_CY into a CY
1476 //
1477 inline _variant_t::operator CY() const 
1478 {
1479       if (V_VT(this) == VT_CY) {
1480              return V_CY(this); 
1481       }
1482
1483       _variant_t varDest;
1484       varDest.ChangeType(VT_CY, this);
1485
1486       return V_CY(&varDest);
1487 }
1488
1489 // Extracts a VT_BSTR into a _bstr_t
1490 //
1491 inline _variant_t::operator _bstr_t() const 
1492 {
1493       if (V_VT(this) == VT_BSTR) {
1494              return V_BSTR(this);
1495       }
1496
1497       _variant_t varDest;
1498       varDest.ChangeType(VT_BSTR, this);
1499
1500       return V_BSTR(&varDest);
1501 }
1502
1503 // Extracts a VT_DISPATCH into an IDispatch*
1504 //
1505 inline _variant_t::operator IDispatch*() const 
1506 {
1507       if (V_VT(this) == VT_DISPATCH) {
1508              if (V_DISPATCH(this) != NULL) {
1509                     V_DISPATCH(this)->AddRef();
1510              }
1511              return V_DISPATCH(this);
1512       }
1513
1514       _variant_t varDest;
1515       varDest.ChangeType(VT_DISPATCH, this);
1516       
1517       if (V_DISPATCH(&varDest) != NULL) {
1518              V_DISPATCH(&varDest)->AddRef();
1519       }
1520
1521       return V_DISPATCH(&varDest);
1522 }
1523
1524 // Extract a VT_BOOL into a bool
1525 //
1526 inline _variant_t::operator bool() const 
1527 {
1528       if (V_VT(this) == VT_BOOL) {
1529              return V_BOOL(this) ? true : false;
1530       }
1531
1532       _variant_t varDest;
1533       varDest.ChangeType(VT_BOOL, this);
1534
1535       return (V_BOOL(&varDest) == VARIANT_TRUE) ? true : false;
1536 }
1537
1538 // Extracts a VT_UNKNOWN into an IUnknown*
1539 //
1540 inline _variant_t::operator IUnknown*() const 
1541 {
1542       if (V_VT(this) == VT_UNKNOWN) {
1543              if (V_UNKNOWN(this) != NULL) {
1544                     V_UNKNOWN(this)->AddRef();
1545              }
1546              return V_UNKNOWN(this);
1547       }
1548
1549       _variant_t varDest;
1550       varDest.ChangeType(VT_UNKNOWN, this);
1551
1552       if (V_UNKNOWN(&varDest) != NULL) {
1553              V_UNKNOWN(&varDest)->AddRef();
1554       }
1555
1556       return V_UNKNOWN(&varDest);
1557 }
1558
1559 // Extracts a VT_DECIMAL into a DECIMAL
1560 //
1561 inline _variant_t::operator DECIMAL() const 
1562 {
1563       if (V_VT(this) == VT_DECIMAL) {
1564              return V_DECIMAL(this);
1565       }
1566
1567       _variant_t varDest;
1568       varDest.ChangeType(VT_DECIMAL, this);
1569
1570       return V_DECIMAL(&varDest);
1571 }
1572
1573 // Extracts a VT_UI1 into a BYTE (unsigned char)
1574 //
1575 inline _variant_t::operator BYTE() const 
1576 {
1577       if (V_VT(this) == VT_UI1) {
1578              return V_UI1(this);
1579       }
1580
1581       _variant_t varDest;
1582       varDest.ChangeType(VT_UI1, this);
1583
1584       return V_UI1(&varDest);
1585 }
1586
1587 // Extract the physical VARIANT
1588 //
1589 inline _variant_t::operator VARIANT() const throw()
1590 {
1591       return *(VARIANT*) this;
1592 }
1593
1594 // Extracts a VT_I1 into a char
1595 //
1596 inline _variant_t::operator char() const  
1597 {
1598       if (V_VT(this) == VT_I1) {
1599              return V_I1(this);
1600       }
1601
1602       _variant_t varDest;
1603       varDest.ChangeType(VT_I1, this);
1604
1605       return V_I1(&varDest);
1606 }
1607
1608 // Extracts a VT_UI2 into a unsigned short
1609 //
1610 inline _variant_t::operator unsigned short() const  
1611 {
1612       if (V_VT(this) == VT_UI2) {
1613              return V_UI2(this);
1614       }
1615
1616       _variant_t varDest;
1617       varDest.ChangeType(VT_UI2, this);
1618
1619       return V_UI2(&varDest);
1620 }
1621
1622 // Extracts a VT_UI4 into a unsigned long
1623 //
1624 inline _variant_t::operator unsigned long() const  
1625 {
1626       if (V_VT(this) == VT_UI4) {
1627              return V_UI4(this);
1628       }
1629
1630       _variant_t varDest;
1631       varDest.ChangeType(VT_UI4, this);
1632
1633       return V_UI4(&varDest);
1634 }
1635
1636 // Extracts a VT_INT into a int
1637 //
1638 inline _variant_t::operator int() const  
1639 {
1640       if (V_VT(this) == VT_INT) {
1641              return V_INT(this);
1642       }
1643
1644       _variant_t varDest;
1645       varDest.ChangeType(VT_INT, this);
1646
1647       return V_INT(&varDest);
1648 }
1649
1650 // Extracts a VT_UINT into a unsigned int
1651 //
1652 inline _variant_t::operator unsigned int() const  
1653 {
1654       if (V_VT(this) == VT_UINT) {
1655              return V_UINT(this);
1656       }
1657
1658       _variant_t varDest;
1659       varDest.ChangeType(VT_UINT, this);
1660
1661       return V_UINT(&varDest);
1662 }
1663
1664 #if (_WIN32_WINNT >= 0x0501)
1665 // Extracts a VT_I8 into a __int64
1666 //
1667 inline _variant_t::operator __int64() const  
1668 {
1669       if (V_VT(this) == VT_I8) {
1670              return V_I8(this);
1671       }
1672
1673       _variant_t varDest;
1674       varDest.ChangeType(VT_I8, this);
1675
1676       return V_I8(&varDest);
1677 }
1678
1679 // Extracts a VT_UI8 into a unsigned __int64
1680 //
1681 inline _variant_t::operator unsigned __int64() const  
1682 {
1683       if (V_VT(this) == VT_UI8) {
1684              return V_UI8(this);
1685       }
1686
1687       _variant_t varDest;
1688       varDest.ChangeType(VT_UI8, this);
1689
1690       return V_UI8(&varDest);
1691 }
1692 #endif
1693
1694 //////////////////////////////////////////////////////////////////////////////////////////
1695 //
1696 // Assignment operations
1697 //
1698 //////////////////////////////////////////////////////////////////////////////////////////
1699
1700 // Assign a const VARIANT& (::VariantCopy handles everything)
1701 //
1702 inline _variant_t& _variant_t::operator=(const VARIANT& varSrc) 
1703 {
1704       _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(&varSrc)));
1705
1706       return *this;
1707 }
1708
1709 // Assign a const VARIANT* (::VariantCopy handles everything)
1710 //
1711 inline _variant_t& _variant_t::operator=(const VARIANT* pSrc) 
1712 {
1713       if (pSrc == NULL) {
1714              _com_issue_error(E_POINTER);
Lines 1715 ... 2038 are skipped.
2039 inline _variant_t& _variant_t::operator=(unsigned long ulSrc) 
2040 {
2041       if (V_VT(this) != VT_UI4) {
2042              // Clear the VARIANT and create a VT_UI4
2043              //
2044              Clear();
2045
2046              V_VT(this) = VT_UI4;
2047       }
2048
2049       V_UI4(this) = ulSrc;
2050
2051       return *this;
2052 }
2053
2054 // Assign a char creating a VT_INT VARIANT
2055 //
2056 inline _variant_t& _variant_t::operator=(int iSrc) 
2057 {
2058       if (V_VT(this) != VT_INT) {
2059              // Clear the VARIANT and create a VT_INT
2060              //
2061              Clear();
2062
2063              V_VT(this) = VT_INT;
2064       }
2065
2066       V_INT(this) = iSrc;
2067
2068       return *this;
2069 }
2070
2071 // Assign a char creating a VT_UINT VARIANT
2072 //
2073 inline _variant_t& _variant_t::operator=(unsigned int uiSrc) 
2074 {
2075       if (V_VT(this) != VT_UINT) {
2076              // Clear the VARIANT and create a VT_UINT
2077              //
2078              Clear();
2079
2080              V_VT(this) = VT_UINT;
2081       }
2082
2083       V_UINT(this) = uiSrc;
2084
2085       return *this;
2086 }
2087
2088 #if (_WIN32_WINNT >= 0x0501)
2089 // Assign a char creating a VT_I8 VARIANT
2090 //
2091 inline _variant_t& _variant_t::operator=(__int64 i8Src) 
2092 {
2093       if (V_VT(this) != VT_I8) {
2094              // Clear the VARIANT and create a VT_I8
2095              //
2096              Clear();
2097
2098              V_VT(this) = VT_I8;
2099       }
2100
2101       V_I8(this) = i8Src;
2102
2103       return *this;
2104 }
2105
2106 // Assign a char creating a VT_UI8 VARIANT
2107 //
2108 inline _variant_t& _variant_t::operator=(unsigned __int64 ui8Src) 
2109 {
2110       if (V_VT(this) != VT_UI8) {
2111              // Clear the VARIANT and create a VT_UI8
2112              //
2113              Clear();
2114
2115              V_VT(this) = VT_UI8;
2116       }
2117
2118       V_UI8(this) = ui8Src;
2119
2120       return *this;
2121 }
2122 #endif
2123
2124 //////////////////////////////////////////////////////////////////////////////////////////
2125 //
2126 // Comparison operations
2127 //
2128 //////////////////////////////////////////////////////////////////////////////////////////
2129
2130 // Compare a _variant_t against a const VARIANT& for equality
2131 //
2132 inline bool _variant_t::operator==(const VARIANT& varSrc) const throw()
2133 {
2134       return *this == &varSrc;
2135 }
2136
2137 #pragma warning(push)
2138 #pragma warning(disable: 4702) // unreachable code
2139
2140 // Compare a _variant_t against a const VARIANT* for equality
2141 //
2142 inline bool _variant_t::operator==(const VARIANT* pSrc) const throw()
2143 {
2144       if (pSrc == NULL) {
2145              return false;
2146       }
2147
2148       if (this == pSrc) {
2149              return true;
2150       }
2151
2152       //
2153       // Variants not equal if types don't match
2154       //
2155       if (V_VT(this) != V_VT(pSrc)) {
2156              return false;
2157       }
2158
2159       //
2160       // Check type specific values
2161       //
2162       switch (V_VT(this)) {
2163              case VT_EMPTY:
2164              case VT_NULL:
2165                     return true;
2166
2167              case VT_I2:
2168                     return V_I2(this) == V_I2(pSrc);
2169
2170              case VT_I4:
2171                     return V_I4(this) == V_I4(pSrc);
2172
2173              case VT_R4:
2174                     return V_R4(this) == V_R4(pSrc);
2175
2176              case VT_R8:
2177                     return V_R8(this) == V_R8(pSrc);
2178
2179              case VT_CY:
2180                     return memcmp(&(V_CY(this)), &(V_CY(pSrc)), sizeof(CY)) == 0;
2181
2182              case VT_DATE:
2183                     return V_DATE(this) == V_DATE(pSrc);
2184
2185              case VT_BSTR:
2186                     return (::SysStringByteLen(V_BSTR(this)) == ::SysStringByteLen(V_BSTR(pSrc))) &&
2187                                  (memcmp(V_BSTR(this), V_BSTR(pSrc), ::SysStringByteLen(V_BSTR(this))) == 0);
2188
2189              case VT_DISPATCH:
2190                     return V_DISPATCH(this) == V_DISPATCH(pSrc);
2191
2192              case VT_ERROR:
2193                     return V_ERROR(this) == V_ERROR(pSrc);
2194
2195              case VT_BOOL:
2196                     return V_BOOL(this) == V_BOOL(pSrc);
2197
2198              case VT_UNKNOWN:
2199                     return V_UNKNOWN(this) == V_UNKNOWN(pSrc);
2200
2201              case VT_DECIMAL:
2202                     return memcmp(&(V_DECIMAL(this)), &(V_DECIMAL(pSrc)), sizeof(DECIMAL)) == 0;
2203
2204              case VT_UI1:
2205                     return V_UI1(this) == V_UI1(pSrc);
2206
2207              case VT_I1:
2208                     return V_I1(this) == V_I1(pSrc);
2209
2210              case VT_UI2:
2211                     return V_UI2(this) == V_UI2(pSrc);
2212
2213              case VT_UI4:
2214                     return V_UI4(this) == V_UI4(pSrc);
2215
2216              case VT_INT:
2217                     return V_INT(this) == V_INT(pSrc);
2218
2219              case VT_UINT:
2220                     return V_UINT(this) == V_UINT(pSrc);
2221
2222 #if (_WIN32_WINNT >= 0x0501)
2223              case VT_I8:
2224                     return V_I8(this) == V_I8(pSrc);
2225
2226              case VT_UI8:
2227                     return V_UI8(this) == V_UI8(pSrc);
2228 #endif
2229
2230              default:
2231                     _com_issue_error(E_INVALIDARG);
2232                     // fall through
2233       }
2234
2235       return false;
2236 }
2237
2238 #pragma warning(pop)
2239
2240 // Compare a _variant_t against a const VARIANT& for in-equality
2241 //
2242 inline bool _variant_t::operator!=(const VARIANT& varSrc) const throw()
2243 {
2244       return !(*this == &varSrc);
2245 }
2246
2247 // Compare a _variant_t against a const VARIANT* for in-equality
2248 //
2249 inline bool _variant_t::operator!=(const VARIANT* pSrc) const throw()
2250 {
2251       return !(*this == pSrc);
2252 }
2253
2254 //////////////////////////////////////////////////////////////////////////////////////////
2255 //
2256 // Low-level operations
2257 //
2258 //////////////////////////////////////////////////////////////////////////////////////////
2259
2260 // Clear the _variant_t
2261 //
2262 inline void _variant_t::Clear() 
2263 {
2264       _com_util::CheckError(::VariantClear(this));
2265 }
2266
2267 inline void _variant_t::Attach(VARIANT& varSrc) 
2268 {
2269       //
2270       // Free up previous VARIANT
2271       //
2272       Clear();
2273
2274       //
2275       // Give control of data to _variant_t
2276       //
2277       _COM_MEMCPY_S(this, sizeof(varSrc), &varSrc, sizeof(varSrc));
2278       V_VT(&varSrc) = VT_EMPTY;
2279 }
2280
2281 inline VARIANT _variant_t::Detach() 
2282 {
2283       VARIANT varResult = *this;
2284       V_VT(this) = VT_EMPTY;
2285
2286       return varResult;
2287 }
2288
2289 inline VARIANT& _variant_t::GetVARIANT() throw() 
2290 {
2291       return *(VARIANT*) this;
2292 }
2293
2294 inline VARIANT* _variant_t::GetAddress() 
2295 {
2296       Clear();
2297       return (VARIANT*) this;
2298 }
2299
2300 // Change the type and contents of this _variant_t to the type vartype and
2301 // contents of pSrc
2302 //
2303 inline void _variant_t::ChangeType(VARTYPE vartype, const _variant_t* pSrc) 
2304 {
2305       //
2306       // If pDest is NULL, convert type in place
2307       //
2308       if (pSrc == NULL) {
2309              pSrc = this;
2310       }
2311
2312       if ((this != pSrc) || (vartype != V_VT(this))) {
2313              _com_util::CheckError(::VariantChangeType(static_cast<VARIANT*>(this),
2314                                                                                    const_cast<VARIANT*>(static_cast<const VARIANT*>(pSrc)),
2315                                                                                    0, vartype));
2316       }
2317 }
2318
2319 inline void _variant_t::SetString(const char* pSrc) 
2320 {
2321       operator=(pSrc);
2322 }
2323
2324 //////////////////////////////////////////////////////////////////////////////////////////
2325 //
2326 // Destructor
2327 //
2328 //////////////////////////////////////////////////////////////////////////////////////////
2329
2330 inline _variant_t::~_variant_t() throw()
2331 {
2332       ::VariantClear(this);
2333 }
2334
2335 //////////////////////////////////////////////////////////////////////////////////////////
2336 //
2337 // Mutually-dependent definitions
2338 //
2339 //////////////////////////////////////////////////////////////////////////////////////////
2340
2341 // Construct a _bstr_t from a const _variant_t&
2342 //
2343 inline _bstr_t::_bstr_t(const _variant_t &var) 
2344       : m_Data(NULL)
2345 {
2346       if (V_VT(&var) == VT_BSTR) {
2347              *this = V_BSTR(&var);
2348              return;
2349       }
2350
2351       _variant_t varDest;
2352       varDest.ChangeType(VT_BSTR, &var);
2353
2354       *this = V_BSTR(&varDest);
2355 }
2356
2357 // Assign a const _variant_t& to a _bstr_t
2358 //
2359 inline _bstr_t& _bstr_t::operator=(const _variant_t &var) 
2360 {
2361       if (V_VT(&var) == VT_BSTR) {
2362              *this = V_BSTR(&var);
2363              return *this;
2364       }
2365
2366       _variant_t varDest;
2367       varDest.ChangeType(VT_BSTR, &var);
2368
2369       *this = V_BSTR(&varDest);
2370
2371       return *this;
2372 }
2373
2374 extern _variant_t vtMissing;
2375
2376 #ifndef _USE_RAW
2377 #define bstr_t _bstr_t
2378 #define variant_t _variant_t
2379 #endif
2380
2381 #pragma pop_macro("new")
2382
2383 #pragma warning(pop)
2384
2385 #endif  // _INC_COMUTIL
2386