337 lines
10 KiB
C++
337 lines
10 KiB
C++
/*++
|
|
|
|
Copyright (C) 1996-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
VAR.H
|
|
|
|
Abstract:
|
|
|
|
CVar & CVarVector.
|
|
|
|
|
|
These are thread-safe translators for VARIANT and SAFEARRAY
|
|
and represent all types support by WBEM.
|
|
|
|
These are mutually nestable to any level. A CVarVector can contain
|
|
an array of CVar, and a CVar can contain a CVarVector. One CVar
|
|
can therefore contain a whole tree of CVar objects, themselves
|
|
containing homogeneous or heterogeneous arrays of CVar objects.
|
|
|
|
Note: CVar should not be bound to one type and then immediately
|
|
coerced to a new type. This object is designed for speed, not safety,
|
|
so there is no checking to see if this has been done. A memory leak
|
|
is likely to occur.
|
|
|
|
The assignment operator and copy constructors are the only method
|
|
of changing the type on a CVar. Do NOT construct the object as
|
|
a BSTR, for example, and then call SetDWORD.
|
|
|
|
History:
|
|
|
|
16-Apr-96 a-raymcc Created.
|
|
12//17/98 sanjes - Partially Reviewed for Out of Memory.
|
|
18-Mar-99 a-dcrews Added out-of-memory exception handling
|
|
|
|
--*/
|
|
|
|
#ifndef _VAR_H_
|
|
#define _VAR_H_
|
|
|
|
#include <flexarry.h>
|
|
#include <safearry.h>
|
|
|
|
|
|
#define VT_EX_CVAR (VT_USERDEFINED | 0x80010000)
|
|
#define VT_EX_CVARVECTOR (VT_USERDEFINED | 0x80010002)
|
|
|
|
class CVarVector;
|
|
|
|
typedef union
|
|
{
|
|
char cVal; // VT_I1
|
|
BYTE bVal; // VT_UI1
|
|
SHORT iVal; // VT_I2
|
|
WORD wVal; // VT_UI2
|
|
LONG lVal; // VT_I4
|
|
DWORD dwVal; // VT_UI4
|
|
VARIANT_BOOL boolVal; // VT_BOOL
|
|
|
|
float fltVal; // VT_R4
|
|
double dblVal; // VT_R8
|
|
|
|
LPSTR pStr; // VT_LPSTR
|
|
LPWSTR pWStr; // VT_LPWSTR
|
|
BSTR Str; // VT_BSTR (stored as VT_LPWSTR)
|
|
|
|
FILETIME Time; // VT_FILETIME
|
|
BLOB Blob; // VT_BLOB
|
|
LPCLSID pClsId; // VT_CLSID
|
|
IUnknown* pUnk; // VT_UNKNOWN
|
|
IDispatch* pDisp; // VT_DISPATCH
|
|
CVarVector *pVarVector; // VT_EX_CVARVECTOR
|
|
|
|
} METAVALUE;
|
|
|
|
|
|
class POLARITY CVar
|
|
{
|
|
private:
|
|
int m_vt;
|
|
METAVALUE m_value;
|
|
int m_nStatus;
|
|
BOOL m_bCanDelete;
|
|
|
|
void Init();
|
|
public:
|
|
enum { no_error, unsupported, failed };
|
|
|
|
CVar() { Init(); }
|
|
~CVar();
|
|
CVar(CVar &);
|
|
CVar& operator =(CVar &);
|
|
|
|
CVar(char c) { Init(); SetChar(c); }
|
|
CVar(BYTE b) { Init(); SetByte(b); }
|
|
CVar(SHORT s) { Init(); SetShort(s); }
|
|
CVar(WORD w) { Init(); SetWord(w); }
|
|
CVar(LONG l) { Init(); SetLong(l); }
|
|
CVar(DWORD dw) { Init(); SetDWORD(dw); }
|
|
CVar(float f) { Init(); SetFloat(f); }
|
|
CVar(double d) { Init(); SetDouble(d); }
|
|
CVar(VARIANT_BOOL b,int){ Init(); SetBool(b); }
|
|
|
|
CVar(LPSTR p, BOOL bAcquire = FALSE)
|
|
{ Init(); SetLPSTR(p, bAcquire); }
|
|
|
|
CVar(LPWSTR p, BOOL bAcquire = FALSE)
|
|
{ Init(); SetLPWSTR(p, bAcquire); }
|
|
|
|
CVar(int, BSTR b, BOOL bAcquire = FALSE)
|
|
{ Init(); SetBSTR(b, bAcquire); }
|
|
// Dummy int required for context, since BSTR is also LPWSTR
|
|
// from Win32 point of view, although the VT_ indicators differ.
|
|
|
|
CVar(CLSID *p, BOOL bAcquire = FALSE)
|
|
{ Init(); SetClsId(p, bAcquire); }
|
|
|
|
CVar(BLOB *p, BOOL bAcquire = FALSE)
|
|
{ Init(); SetBlob(p, bAcquire); }
|
|
|
|
CVar(FILETIME *p) { Init(); SetFileTime(p); }
|
|
|
|
CVar(CVarVector *p, BOOL bAcquire = FALSE) { Init(); SetVarVector(p, bAcquire); }
|
|
CVar(VARIANT *p) { Init(); SetVariant(p); }
|
|
CVar(int nType, SAFEARRAY *p) { Init(); SetSafeArray(nType, p); }
|
|
int Status() { return m_nStatus; }
|
|
|
|
int DumpText(FILE *fStream);
|
|
int GetType() { return m_vt; }
|
|
int GetOleType();
|
|
void Empty();
|
|
|
|
int operator ==(CVar &Other);
|
|
BOOL CompareTo(CVar& Other, BOOL bIgnoreCase);
|
|
|
|
|
|
void SetRaw(int vt, void* pvData, int nDataLen);
|
|
void* GetRawData() {return (void*)&m_value;}
|
|
BOOL CanDelete() {return m_bCanDelete;}
|
|
void SetCanDelete(BOOL bCanDelete) {m_bCanDelete = bCanDelete;}
|
|
|
|
// Numeric types.
|
|
// ==============
|
|
|
|
void SetAsNull() { m_vt = VT_NULL; m_value.lVal = 0; }
|
|
BOOL IsNull() {return m_vt == VT_NULL;}
|
|
BOOL IsDataNull();
|
|
|
|
void SetChar(char c) { m_vt = VT_I1; m_value.cVal = c; }
|
|
char GetChar() { return m_value.cVal; }
|
|
operator char() { return m_value.cVal; }
|
|
|
|
void SetByte(BYTE b) { m_vt = VT_UI1; m_value.bVal = b; }
|
|
BYTE GetByte() { return m_value.bVal; }
|
|
operator BYTE() { return m_value.bVal; }
|
|
|
|
void SetShort(SHORT iVal) { m_vt = VT_I2; m_value.iVal = iVal; }
|
|
SHORT GetShort() { return m_value.iVal; }
|
|
operator SHORT() { return m_value.iVal; }
|
|
|
|
void SetWord(WORD wVal) { m_vt = VT_UI2; m_value.wVal = wVal; }
|
|
WORD GetWord() { return m_value.wVal; }
|
|
operator WORD() { return m_value.wVal; }
|
|
|
|
void SetLong(LONG lVal) { m_value.lVal = lVal; m_vt = VT_I4; }
|
|
LONG GetLong() { return m_value.lVal; }
|
|
operator LONG() { return m_value.lVal; }
|
|
|
|
void SetDWORD(DWORD dwVal) { m_value.dwVal = dwVal; m_vt = VT_UI4; }
|
|
DWORD GetDWORD() { return m_value.dwVal; }
|
|
operator DWORD() { return m_value.dwVal; }
|
|
|
|
void SetBool(VARIANT_BOOL b) { m_value.boolVal = b; m_vt = VT_BOOL; }
|
|
VARIANT_BOOL GetBool() { return m_value.boolVal; }
|
|
|
|
void SetFloat(float f) { m_value.fltVal = f; m_vt = VT_R4; }
|
|
float GetFloat() { return m_value.fltVal; }
|
|
operator float() { return m_value.fltVal; }
|
|
|
|
void SetDouble(double dblVal) { m_value.dblVal = dblVal; m_vt = VT_R8; }
|
|
double GetDouble() { return m_value.dblVal; }
|
|
operator double() { return m_value.dblVal; }
|
|
|
|
void SetDispatch(IDispatch* pDisp);
|
|
IDispatch* GetDispatch()
|
|
{if(m_value.pDisp) m_value.pDisp->AddRef(); return m_value.pDisp;}
|
|
|
|
void SetUnknown(IUnknown* pUnk);
|
|
IUnknown* GetUnknown()
|
|
{if(m_value.pUnk) m_value.pUnk->AddRef(); return m_value.pUnk;}
|
|
|
|
void SetEmbeddedObject(IUnknown* pUnk) {SetUnknown(pUnk);}
|
|
IUnknown* GetEmbeddedObject() {return GetUnknown();}
|
|
|
|
int SetVariant(VARIANT *pSrc, BOOL fOptimize = FALSE);
|
|
|
|
void FillVariant(VARIANT* pDest, BOOL fOptimized = FALSE);
|
|
VARIANT *GetNewVariant();
|
|
|
|
// String types.
|
|
// =============
|
|
|
|
BOOL SetLPWSTR(LPWSTR pVal, BOOL bAcquire = FALSE);
|
|
wchar_t *GetLPWSTR() { return m_value.pWStr; }
|
|
operator LPWSTR() { return m_value.pWStr; }
|
|
|
|
BOOL SetLPSTR(LPSTR pStr, BOOL bAcquire = FALSE);
|
|
LPSTR GetLPSTR() { return m_value.pStr; }
|
|
operator LPSTR() { return m_value.pStr; }
|
|
|
|
BOOL SetBSTR(BSTR str, BOOL bAcquire = FALSE);
|
|
BSTR GetBSTR(); // Makes a dynamic copy which must be freed.
|
|
|
|
// Misc. types.
|
|
// ============
|
|
|
|
void SetFileTime(FILETIME *pft) { m_value.Time = *pft; m_vt = VT_FILETIME; }
|
|
FILETIME GetFileTime() { return m_value.Time; }
|
|
operator FILETIME() { return m_value.Time; }
|
|
|
|
void SetBlob(BLOB *pBlob, BOOL bAcquire = FALSE);
|
|
BLOB *GetBlob() { return &m_value.Blob; }
|
|
operator BLOB *() { return &m_value.Blob; }
|
|
|
|
void SetClsId(CLSID *pClsId, BOOL bAcquire);
|
|
CLSID* GetClsId() { return m_value.pClsId; } // Return value is read-only
|
|
operator CLSID*() { return m_value.pClsId; } // Return value is read-only
|
|
|
|
void SetVarVector(CVarVector *pVec, BOOL bAcquire);
|
|
CVarVector *GetVarVector() { return m_value.pVarVector; }
|
|
operator CVarVector *() { return m_value.pVarVector; }
|
|
|
|
void SetSafeArray(int nType, SAFEARRAY *pArray); // Copies the source
|
|
SAFEARRAY *GetNewSafeArray(); // New SAFEARRAY which must be released
|
|
|
|
void SetOptimizedSafeArray(int nType, SAFEARRAY *pArray, BOOL fAcquire = FALSE);
|
|
SAFEARRAY* GetOptimizedSafeArray( void );
|
|
|
|
static BSTR TypeToText(int nType);
|
|
BSTR GetTypeText();
|
|
BSTR GetText(long lFlags, long lType = 0, LPCWSTR szFormat = NULL);
|
|
|
|
BOOL ChangeTypeTo(VARTYPE vtNew);
|
|
BOOL ChangeTypeToEx(VARTYPE vtNew, LCID lcid = 0x409 );
|
|
BOOL ToSingleChar();
|
|
BOOL ToUI4();
|
|
};
|
|
|
|
|
|
class POLARITY CVarVector
|
|
{
|
|
int m_nType;
|
|
CFlexArray m_Array;
|
|
int m_nStatus;
|
|
CSafeArray* m_pSafeArray;
|
|
void* m_pRawData;
|
|
|
|
public:
|
|
enum { no_error, failed, unsupported };
|
|
|
|
CVarVector();
|
|
CVarVector(int nVarType, int nInitSize = 32, int nGrowBy = 32);
|
|
|
|
// These two only support limited SAFEARRAY types.
|
|
// ===============================================
|
|
|
|
CVarVector(int nVarType, SAFEARRAY *pSrc, BOOL fOptimized = FALSE);
|
|
SAFEARRAY *GetNewSafeArray();
|
|
SAFEARRAY* GetSafeArray( BOOL fAcquire = FALSE );
|
|
|
|
int GetType() { return m_nType; }
|
|
int Status() { return m_nStatus; }
|
|
void Empty();
|
|
|
|
~CVarVector();
|
|
CVarVector(CVarVector &Src);
|
|
CVarVector& operator =(CVarVector &Src);
|
|
int operator ==(CVarVector &Src);
|
|
BOOL CompareTo(CVarVector& Other, BOOL bIgnoreCase);
|
|
int Size();
|
|
|
|
int Add(CVar &Value);
|
|
int Add(CVar *pAcquiredPtr);
|
|
|
|
CVar& GetAt(int nIndex);
|
|
CVar& operator [](int nIndex);
|
|
|
|
int RemoveAt(int nIndex);
|
|
int InsertAt(int nIndex, CVar &Value);
|
|
|
|
BSTR GetText(long lFlags, long lType = 0);
|
|
BOOL ToSingleChar();
|
|
BOOL ToUI4();
|
|
|
|
BOOL IsOptimized( void ) { return NULL != m_pSafeArray; }
|
|
BOOL MakeOptimized( int nVarType, int nInitSize = 32, int nGrowBy = 32 );
|
|
void SetRawArrayBinding( int nBinding );
|
|
|
|
HRESULT AccessRawArray( void** ppv );
|
|
HRESULT UnaccessRawArray( void );
|
|
|
|
// We access raw data using internal data member.
|
|
HRESULT InternalRawArrayAccess( void );
|
|
|
|
static BOOL IsValidVectorType( int nVarType );
|
|
static BOOL IsValidVectorArray( int nVarType, SAFEARRAY* pArray );
|
|
|
|
void FillCVarAt(int nIndex, CVar& vTemp);
|
|
|
|
BOOL DoesVectorTypeMatchArrayType( void );
|
|
|
|
HRESULT SetRawArrayData( void* pvData, int nNumElements, int nElementSize );
|
|
HRESULT GetRawArrayData( void* pvDest, int nBuffSize );
|
|
|
|
BOOL SetRawArraySize( int nSize );
|
|
int GetElementSize( void );
|
|
};
|
|
|
|
class CUnaccessVarVector
|
|
{
|
|
private:
|
|
CVarVector* m_pVV;
|
|
|
|
public:
|
|
|
|
CUnaccessVarVector( CVarVector* pvv = NULL ) : m_pVV( pvv ) {}
|
|
~CUnaccessVarVector() { Unaccess(); }
|
|
|
|
void SetVV( CVarVector* pvv ) { m_pVV = pvv; }
|
|
void Unaccess( void ) { if ( NULL != m_pVV ) m_pVV->UnaccessRawArray(); m_pVV = NULL; }
|
|
};
|
|
|
|
#endif
|
|
|
|
|