1847 lines
42 KiB
C++
1847 lines
42 KiB
C++
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Microsoft WMIOLE DB Provider
|
|
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// dataconvert.cpp
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "headers.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This function returns the default OLE DB representation for a data type
|
|
//
|
|
// To be used only to create tables or any other things
|
|
// But should not be used for setting properties of type ARRAYS
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::MapOLEDBTypeToCIMType(WORD wDataType, long & lCIMType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bArray = FALSE;
|
|
|
|
if( wDataType & DBTYPE_ARRAY)
|
|
{
|
|
bArray = TRUE;
|
|
wDataType = wDataType & ~DBTYPE_ARRAY;
|
|
}
|
|
|
|
switch( wDataType ){
|
|
|
|
case DBTYPE_I1:
|
|
lCIMType = CIM_SINT8;
|
|
break;
|
|
|
|
case DBTYPE_UI1:
|
|
lCIMType = CIM_UINT8;
|
|
break;
|
|
|
|
case DBTYPE_I2:
|
|
lCIMType = CIM_SINT16;
|
|
break;
|
|
|
|
case DBTYPE_UI2:
|
|
lCIMType = CIM_UINT16;
|
|
break;
|
|
|
|
case DBTYPE_I4:
|
|
lCIMType = CIM_SINT32;
|
|
break;
|
|
|
|
case DBTYPE_UI4:
|
|
lCIMType = CIM_UINT32;
|
|
break;
|
|
|
|
case DBTYPE_I8:
|
|
lCIMType = CIM_SINT64;
|
|
break;
|
|
|
|
case DBTYPE_UI8:
|
|
lCIMType = CIM_UINT64;
|
|
break;
|
|
|
|
case DBTYPE_R4:
|
|
lCIMType = CIM_REAL32;
|
|
break;
|
|
|
|
case DBTYPE_R8:
|
|
lCIMType = CIM_REAL64;
|
|
break;
|
|
|
|
case DBTYPE_BOOL:
|
|
lCIMType = CIM_BOOLEAN;
|
|
break;
|
|
|
|
case DBTYPE_WSTR:
|
|
case DBTYPE_BSTR:
|
|
case DBTYPE_STR:
|
|
lCIMType = CIM_STRING;
|
|
break;
|
|
|
|
case DBTYPE_DATE :
|
|
case DBTYPE_DBTIME :
|
|
case DBTYPE_DBTIMESTAMP:
|
|
lCIMType = CIM_DATETIME;
|
|
break;
|
|
|
|
case DBTYPE_IDISPATCH :
|
|
case DBTYPE_IUNKNOWN :
|
|
lCIMType = CIM_IUNKNOWN;
|
|
break;
|
|
|
|
case DBTYPE_VARIANT:
|
|
hr = E_FAIL;
|
|
break;
|
|
|
|
|
|
default:
|
|
assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
|
|
}
|
|
|
|
if( bArray == TRUE)
|
|
{
|
|
lCIMType |= CIM_FLAG_ARRAY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to Map CIMType to OLEDB type and allocate memory for the data
|
|
// NTRaid:111819 - 111822
|
|
// 06/07/00
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::AllocateAndMapCIMTypeToOLEDBType(CVARIANT & vValue,BYTE *& pData,DBTYPE & dwColType,DBLENGTH & dwSize, DWORD &dwFlags)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
SAFEARRAY *pArray = NULL;
|
|
LONG lType= 0;
|
|
VARIANT *pVar = NULL,*pvar2 = NULL;
|
|
pData = NULL;
|
|
|
|
lType = vValue.GetType();
|
|
if(lType != VT_NULL && lType != VT_NULL)
|
|
{
|
|
lType = dwColType;
|
|
// If the type is of some array
|
|
if (dwColType & CIM_FLAG_ARRAY)
|
|
{
|
|
lType = CIM_FLAG_ARRAY;
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
switch( lType ){
|
|
|
|
case VT_NULL:
|
|
pData = NULL;
|
|
hr = DBSTATUS_S_ISNULL;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case VT_EMPTY:
|
|
pData = NULL;
|
|
hr = DBSTATUS_S_ISNULL;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
// Arrays are always shown as ARRAY of VARIANTS to make it easily accessible with scripting
|
|
case CIM_FLAG_ARRAY:
|
|
lType = vValue.GetType();
|
|
// since date is given out as string from WMI
|
|
if(IsDateType((DBTYPE)dwColType))
|
|
{
|
|
lType = dwColType;
|
|
}
|
|
hr = ConvertToVariantArray(((VARIANT *)&vValue)->parray,(DBTYPE)lType,(SAFEARRAY **)&pData);
|
|
dwSize = sizeof(SAFEARRAY);
|
|
dwColType = VT_ARRAY | VT_VARIANT;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT8:
|
|
case CIM_UINT8:
|
|
pData = new BYTE[1];
|
|
if(pData)
|
|
{
|
|
*pData = (BYTE)vValue.GetByte();
|
|
dwSize = sizeof(BYTE);
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_CHAR16:
|
|
case CIM_SINT16:
|
|
case CIM_UINT16:
|
|
case CIM_BOOLEAN:
|
|
{
|
|
dwSize = sizeof(short);
|
|
pData = new BYTE[dwSize];
|
|
short tmp = vValue.GetShort();
|
|
if(pData)
|
|
{
|
|
memcpy(pData,(BYTE*)&tmp,dwSize);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT32:
|
|
case CIM_UINT32:
|
|
case CIM_REAL32:
|
|
{
|
|
dwSize = sizeof(long);
|
|
long tmp = vValue.GetLONG();
|
|
pData = new BYTE[dwSize];
|
|
if(pData)
|
|
{
|
|
memset(pData,0,dwSize);
|
|
memcpy(pData,(BYTE*)&tmp,dwSize);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_REAL64:
|
|
{
|
|
dwSize = 8;
|
|
double dblVal = vValue.GetDouble();
|
|
pData = new BYTE[dwSize];
|
|
if(pData)
|
|
{
|
|
memcpy(pData,&dblVal,dwSize);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
dwSize = sizeof(DBTIMESTAMP);
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
if( vValue.GetStr() != NULL)
|
|
{
|
|
pData = new BYTE[dwSize];
|
|
if(pData)
|
|
{
|
|
hr = ConvertDateToOledbType(vValue.GetStr(),(DBTIMESTAMP *)pData);
|
|
dwColType = DBTYPE_DBTIMESTAMP;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = DBSTATUS_S_ISNULL;
|
|
pData = NULL;
|
|
dwSize = 0;
|
|
}
|
|
break;
|
|
|
|
case VT_DATE:
|
|
dwSize = sizeof(DBTIMESTAMP);
|
|
pData = new BYTE[dwSize];
|
|
if(pData)
|
|
{
|
|
ConvertVariantDateOledbDate(&((VARIANT *)&vValue)->date,(DBTIMESTAMP *)pData);
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
dwColType = DBTYPE_DBTIMESTAMP;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
pData = (BYTE *)Wmioledb_SysAllocString(vValue.GetStr());
|
|
dwSize = SysStringLen(vValue.GetStr());
|
|
break;
|
|
|
|
case CIM_REFERENCE:
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
break;
|
|
|
|
case CIM_IUNKNOWN:
|
|
pData = new BYTE[sizeof(IUnknown *)];
|
|
if(pData)
|
|
{
|
|
memset(pData,0,sizeof(IUnknown *));
|
|
hr = vValue.GetUnknown()->QueryInterface(IID_IUnknown,(void **)pData);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case VT_VARIANT:
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
dwSize = sizeof(VARIANT);
|
|
pVar = new VARIANT;
|
|
if(pVar)
|
|
{
|
|
VariantInit(pVar);
|
|
hr = VariantCopy(pVar,vValue);
|
|
dwColType = DBTYPE_VARIANT;
|
|
pData = (BYTE *) pVar;
|
|
pvar2 = (VARIANT *)pData;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
|
|
}
|
|
} // try
|
|
catch(...)
|
|
{
|
|
switch( lType )
|
|
{
|
|
|
|
case CIM_FLAG_ARRAY:
|
|
{
|
|
if(pData)
|
|
{
|
|
SafeArrayDestroy((SAFEARRAY *)pData);
|
|
}
|
|
}
|
|
break;
|
|
case CIM_STRING:
|
|
{
|
|
if(pData)
|
|
{
|
|
SysFreeString((BSTR)pData);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_VARIANT:
|
|
{
|
|
SAFE_DELETE_PTR((VARIANT *&)pData);
|
|
}
|
|
break;
|
|
|
|
case CIM_IUNKNOWN:
|
|
if(pData)
|
|
{
|
|
(*(IUnknown **)pData)->Release();
|
|
SAFE_DELETE_ARRAY(pData);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
{
|
|
SAFE_DELETE_ARRAY(pData);
|
|
}
|
|
break;
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Free the data allocated to store data
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::FreeData(DBTYPE lType, BYTE *& pData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
VARIANT *pVar = NULL;
|
|
|
|
//=======================================================================
|
|
// See if it is an array
|
|
//=======================================================================
|
|
/* if( lType & CIM_FLAG_ARRAY ){
|
|
lType = lType &~ CIM_FLAG_ARRAY;
|
|
fArray = TRUE;
|
|
}
|
|
*/
|
|
// If the pointer sent is not NULL
|
|
if( lType & CIM_FLAG_ARRAY )
|
|
{
|
|
lType = CIM_FLAG_ARRAY;
|
|
}
|
|
|
|
if(pData)
|
|
{
|
|
switch( lType ){
|
|
|
|
case VT_EMPTY:
|
|
break;
|
|
|
|
case VT_NULL:
|
|
break;
|
|
|
|
case CIM_FLAG_ARRAY:
|
|
pVar = (VARIANT *)pData;
|
|
hr = SafeArrayDestroy((SAFEARRAY *)pData);
|
|
break;
|
|
|
|
case CIM_UINT8:
|
|
case CIM_SINT8:
|
|
SAFE_DELETE_PTR((BYTE*)pData);
|
|
break;
|
|
|
|
case CIM_BOOLEAN:
|
|
case CIM_CHAR16:
|
|
case CIM_SINT16:
|
|
case CIM_UINT16:
|
|
SAFE_DELETE_PTR((short*&)pData);
|
|
break;
|
|
|
|
case CIM_REAL32:
|
|
case CIM_SINT32:
|
|
case CIM_UINT32:
|
|
SAFE_DELETE_PTR((DWORD*&)pData);
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_REAL64:
|
|
SAFE_DELETE_ARRAY((BYTE*)pData);
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
SAFE_DELETE_PTR((DBTIMESTAMP *&)pData);
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
SysFreeString((BSTR)pData);
|
|
break;
|
|
|
|
case CIM_REFERENCE:
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
case CIM_IUNKNOWN:
|
|
// case DBTYPE_IUNKNOWN:
|
|
if(pData)
|
|
{
|
|
SAFE_RELEASE_PTR((*(IUnknown **)pData));
|
|
SAFE_DELETE_ARRAY(pData);
|
|
}
|
|
break;
|
|
|
|
case VT_VARIANT:
|
|
hr = VariantClear((VARIANT *)pData);
|
|
SAFE_DELETE_PTR((VARIANT *&)pData);
|
|
break;
|
|
|
|
case DBTYPE_DATE:
|
|
SAFE_DELETE_PTR((DATE *&)pData);
|
|
break;
|
|
|
|
|
|
default:
|
|
assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
|
|
}
|
|
}
|
|
if(hr == S_OK)
|
|
pData = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This function returns the default OLE DB representation for a data type
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::MapCIMTypeToOLEDBType(long lType, WORD & wdbOLEDBType, DBLENGTH & uColumnSize , DWORD &dwFlags) // OUT OLE DB type for DBColumnInfo
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LONG lCimType = lType;
|
|
|
|
if ( lType & CIM_FLAG_ARRAY)
|
|
{
|
|
lCimType = CIM_FLAG_ARRAY;
|
|
}
|
|
|
|
switch( lCimType ){
|
|
|
|
case VT_EMPTY:
|
|
wdbOLEDBType = DBTYPE_EMPTY;
|
|
uColumnSize = 0;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case VT_NULL:
|
|
wdbOLEDBType = DBTYPE_NULL;
|
|
uColumnSize = 0;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT8:
|
|
wdbOLEDBType = DBTYPE_I1;
|
|
uColumnSize = 1;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_UINT8:
|
|
wdbOLEDBType = DBTYPE_UI1;
|
|
uColumnSize = 1;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT16:
|
|
wdbOLEDBType = DBTYPE_I2;
|
|
uColumnSize = 2;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_UINT16:
|
|
wdbOLEDBType = DBTYPE_UI2;
|
|
uColumnSize = 2;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT32:
|
|
wdbOLEDBType = DBTYPE_I4;
|
|
uColumnSize = 4;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_UINT32:
|
|
wdbOLEDBType = DBTYPE_UI4;
|
|
uColumnSize = 4;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
wdbOLEDBType = DBTYPE_I8 ; //DBTYPE_R8; //DBTYPE_I8;
|
|
uColumnSize = 8;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_UINT64:
|
|
wdbOLEDBType = DBTYPE_UI8 ; //DBTYPE_R8; //DBTYPE_UI8;
|
|
uColumnSize = 8;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_REAL32:
|
|
wdbOLEDBType = DBTYPE_R4;
|
|
uColumnSize = 4;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_REAL64:
|
|
wdbOLEDBType = DBTYPE_R8;
|
|
uColumnSize = 8;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_BOOLEAN:
|
|
wdbOLEDBType = DBTYPE_BOOL;
|
|
uColumnSize = 2;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
wdbOLEDBType = DBTYPE_BSTR;
|
|
uColumnSize = ~0 ;//MAX_CIM_STRING_SIZE; //sizeof(BSTR); // set the size to -1 ( a variable length string)
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
case VT_DATE :
|
|
wdbOLEDBType = DBTYPE_DBTIMESTAMP;
|
|
uColumnSize = sizeof(DBTIMESTAMP);
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_REFERENCE:
|
|
wdbOLEDBType = DBTYPE_BSTR;
|
|
uColumnSize = sizeof(BSTR);
|
|
break;
|
|
|
|
case CIM_CHAR16:
|
|
wdbOLEDBType = DBTYPE_STR;
|
|
uColumnSize = 2;
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
wdbOLEDBType = DBTYPE_BSTR;
|
|
uColumnSize = sizeof(BSTR);
|
|
break;
|
|
|
|
case CIM_FLAG_ARRAY:
|
|
|
|
wdbOLEDBType = VT_ARRAY | VT_VARIANT;
|
|
uColumnSize = sizeof(SAFEARRAY);
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case DBTYPE_GUID:
|
|
wdbOLEDBType = DBTYPE_GUID;
|
|
uColumnSize = sizeof(GUID);
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
case CIM_IUNKNOWN:
|
|
wdbOLEDBType = DBTYPE_IUNKNOWN;
|
|
uColumnSize = sizeof(IUnknown *);
|
|
dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
|
|
break;
|
|
|
|
default:
|
|
assert( !"Unmatched CIMTYPE to OLEDB Data Type." );
|
|
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// This function translates text strings to OLEDB types
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::TranslateParameterStringToOLEDBType( DBTYPE & wDataType, WCHAR * str)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Arrays ????
|
|
|
|
wDataType = 999;
|
|
|
|
if( 0 == _wcsicmp(L"DBTYPE_CHAR",str )){
|
|
wDataType = DBTYPE_STR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_VARCHAR",str )){
|
|
wDataType = DBTYPE_STR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_LONGVARCHAR",str )){
|
|
wDataType = DBTYPE_STR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_WCHAR",str )){
|
|
wDataType = DBTYPE_WSTR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_WVARCHAR",str )){
|
|
wDataType = DBTYPE_WSTR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_WLONGVARCHAR",str )){
|
|
wDataType = DBTYPE_WSTR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_UI1",str )){
|
|
wDataType = DBTYPE_UI1;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_I1",str )){
|
|
wDataType = DBTYPE_I1;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_I2",str )){
|
|
wDataType = DBTYPE_I2;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_UI2",str )){
|
|
wDataType = DBTYPE_UI2;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_I4",str )){
|
|
wDataType = DBTYPE_I4;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_UI4",str )){
|
|
wDataType = DBTYPE_UI4;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_I8",str )){
|
|
wDataType = DBTYPE_I8;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_UI8",str )){
|
|
wDataType = DBTYPE_UI8;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_R4",str )){
|
|
wDataType = DBTYPE_R4;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_R8",str )){
|
|
wDataType = DBTYPE_R8;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_BOOL",str )){
|
|
wDataType = DBTYPE_BOOL;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_WSTR",str )){
|
|
wDataType = DBTYPE_WSTR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_BSTR",str )){
|
|
wDataType = DBTYPE_BSTR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_STR",str )){
|
|
wDataType = DBTYPE_STR;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_DATE ",str )){
|
|
wDataType = DBTYPE_DATE ;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_DBTIME ",str )){
|
|
wDataType = DBTYPE_DBTIME ;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_DBTIMESTAMP",str )){
|
|
wDataType = DBTYPE_DBTIMESTAMP;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_IDISPATCH",str )){
|
|
wDataType = DBTYPE_IDISPATCH;
|
|
}
|
|
else if( 0 == _wcsicmp(L"DBTYPE_IUNKNOWN",str )){
|
|
wDataType = DBTYPE_IUNKNOWN;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// This function maps and converts OLEDBTYPE to CIMTYPE
|
|
//
|
|
// Note:
|
|
// dwArrayCIMType = -1 - If data passed is not array
|
|
// dwArrayCIMType = actual CIMTYPE - If the passed data is array
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::MapAndConvertOLEDBTypeToCIMType(DBTYPE wDataType, void *pData ,DBLENGTH dwSrcLength, VARIANT &varData,LONG_PTR lArrayCIMType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwDstStatus = 0 , cbDstMaxLength = 0;
|
|
void *pSrc = NULL;
|
|
BSTR strDate=Wmioledb_SysAllocString(NULL);
|
|
SAFEARRAY * pArrayTemp = NULL;
|
|
DBLENGTH dbDstLen = 0;
|
|
|
|
if(lArrayCIMType == -1)
|
|
{
|
|
if(wDataType == VT_BSTR)
|
|
pSrc = &pData;
|
|
else
|
|
pSrc = pData;
|
|
|
|
switch( wDataType )
|
|
{
|
|
case DBTYPE_UI1:
|
|
case DBTYPE_I1:
|
|
wDataType = DBTYPE_I2;
|
|
break;
|
|
|
|
case DBTYPE_UI2:
|
|
wDataType = DBTYPE_I2;
|
|
break;
|
|
|
|
case DBTYPE_UI4:
|
|
wDataType = DBTYPE_I4;
|
|
break;
|
|
|
|
case DBTYPE_DBTIMESTAMP:
|
|
if(IsValidDBTimeStamp((DBTIMESTAMP *)pData))
|
|
{
|
|
// Converts OLEDB DBTIMESTAMP to DMTF date format
|
|
ConvertOledbDateToCIMType((DBTIMESTAMP *)pData,strDate);
|
|
pSrc = &strDate;
|
|
wDataType = VT_BSTR;
|
|
}
|
|
else
|
|
hr = DBSTATUS_E_CANTCONVERTVALUE;
|
|
|
|
}
|
|
}
|
|
else
|
|
// if the type is array then convert it into the appropriate type
|
|
if( (wDataType & DBTYPE_ARRAY) && (lArrayCIMType & DBTYPE_ARRAY))
|
|
{
|
|
hr = ConvertAndCopyArray((SAFEARRAY *)pData, &pArrayTemp, wDataType,(DBTYPE)lArrayCIMType,&dwDstStatus);
|
|
wDataType = (DBTYPE)lArrayCIMType;
|
|
pSrc = pArrayTemp;
|
|
}
|
|
if( hr == S_OK)
|
|
{
|
|
hr = g_pIDataConvert->DataConvert( wDataType, VT_VARIANT, dwSrcLength, &dbDstLen, pSrc,
|
|
&varData, sizeof(VARIANT), 0, &dwDstStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
|
|
}
|
|
|
|
// Release memory
|
|
if( pArrayTemp)
|
|
{
|
|
SafeArrayDestroy(pArrayTemp);
|
|
pArrayTemp = NULL;
|
|
}
|
|
|
|
SysFreeString(strDate);
|
|
return hr;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// This function maps and converts OLEDBTYPE to CIMTYPE
|
|
//
|
|
// Note:
|
|
// dwArrayCIMType = -1 - If data passed is not array
|
|
// dwArrayCIMType = actual CIMTYPE - If the passed data is array
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertToCIMType(BYTE *pData, DBTYPE lType ,DBLENGTH lDataLength,LONG lCIMType ,VARIANT &varData)
|
|
{
|
|
HRESULT hr = DBSTATUS_E_CANTCONVERTVALUE;
|
|
DWORD dwDstStatus = 0;
|
|
DWORD cbDstMaxLength = 0;
|
|
void * pDst = NULL;
|
|
void * pSrc = NULL;
|
|
void * pTemp = NULL;
|
|
BYTE * pbTemp = NULL;
|
|
BSTR strDate = Wmioledb_SysAllocString(NULL);
|
|
SAFEARRAY * pArrayTemp = NULL;
|
|
BOOL bAlloc = FALSE;
|
|
DBLENGTH dbDstLen = 0;
|
|
DBTYPE wDataType = 0;
|
|
BOOL bConverted = FALSE;
|
|
|
|
wDataType = (DBTYPE)lCIMType;
|
|
|
|
if(! pData)
|
|
{
|
|
VariantClear(&varData);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
switch(lCIMType)
|
|
{
|
|
case CIM_UINT8:
|
|
wDataType = VT_I2;
|
|
break;
|
|
|
|
case CIM_UINT16:
|
|
wDataType = VT_I2;
|
|
break;
|
|
|
|
case CIM_UINT32:
|
|
wDataType = VT_I4;
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
BSTR strDate;
|
|
pTemp = new BYTE[sizeof(DBTIMESTAMP)];
|
|
|
|
if( lType == VT_BSTR)
|
|
pSrc = *(BSTR **)pData;
|
|
else
|
|
pSrc = pData;
|
|
|
|
//NTRaid:111795
|
|
// 06/07/00
|
|
if(pTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
// Convert the given date to DBTIMESTAMP
|
|
if( S_OK == (hr = g_pIDataConvert->DataConvert( (DBTYPE)lType,DBTYPE_DBTIMESTAMP, lDataLength,&dbDstLen, pSrc,
|
|
pTemp, sizeof(DBTIMESTAMP), 0, &dwDstStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT)) && dwDstStatus != DBSTATUS_S_ISNULL)
|
|
|
|
{
|
|
// Call this function to convert DBTIMESTAMP date to CIM date format
|
|
if(S_OK == (hr = ConvertOledbDateToCIMType((DBTIMESTAMP*)pTemp,strDate)))
|
|
{
|
|
varData.vt = VT_BSTR;
|
|
varData.bstrVal = Wmioledb_SysAllocString(strDate);
|
|
SysFreeString(strDate);
|
|
}
|
|
}
|
|
SAFE_DELETE_ARRAY(pTemp);
|
|
bConverted = TRUE;
|
|
break;
|
|
|
|
}
|
|
|
|
if(bConverted == FALSE)
|
|
{
|
|
pTemp = pData;
|
|
hr = S_OK;
|
|
// if the required type and the type of the data passed is different then convert the data to appropriate
|
|
// type
|
|
if( lType != (LONG)wDataType && (hr = g_pIDataConvert->CanConvert((DBTYPE)lType,(DBTYPE)wDataType)) == S_OK)
|
|
{
|
|
pTemp = NULL;
|
|
if(SUCCEEDED(hr = AllocateData(wDataType,pTemp,dbDstLen)))
|
|
{
|
|
bAlloc = TRUE;
|
|
|
|
if( lType == VT_BSTR)
|
|
pSrc = (BYTE *)*((BSTR **)pData);
|
|
else
|
|
pSrc = pData;
|
|
|
|
hr = g_pIDataConvert->DataConvert( (DBTYPE)lType,(DBTYPE)wDataType, lDataLength,&dbDstLen, pSrc,
|
|
pTemp, dbDstLen, 0, &dwDstStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
}
|
|
}
|
|
if( hr == S_OK)
|
|
{
|
|
|
|
if( wDataType == VT_BSTR)
|
|
pSrc = *(BSTR **)pTemp;
|
|
else
|
|
pSrc = pTemp;
|
|
|
|
hr = g_pIDataConvert->DataConvert((DBTYPE)wDataType, VT_VARIANT, dbDstLen, &dbDstLen, pSrc,
|
|
&varData, sizeof(VARIANT), 0, &dwDstStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
}
|
|
if( bAlloc == TRUE)
|
|
{
|
|
pbTemp = (BYTE *)pTemp;
|
|
FreeData(wDataType,pbTemp);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SysFreeString(strDate);
|
|
return hr;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// This function convert data to the OLEDBTYPE required. It also allocates memory for the data
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::AllocateAndConvertToOLEDBType(VARIANT &varData,LONG lCimType , DBTYPE lOledbType,BYTE *&pData, DBLENGTH &lDataLength, DBSTATUS &dwStatus)
|
|
{
|
|
HRESULT hr = DBSTATUS_E_CANTCONVERTVALUE;
|
|
DBTYPE wDataType = 0;
|
|
DBLENGTH dwDstLength = 0;
|
|
BYTE *pSrc = NULL;
|
|
void *pTemp = NULL;
|
|
void *pDst = NULL;
|
|
BOOL bConvert = FALSE;
|
|
BOOL bAlloc = FALSE;
|
|
DBLENGTH dbDstLen = 0;
|
|
|
|
wDataType = (DBTYPE)lCimType;
|
|
|
|
if(wDataType & CIM_FLAG_ARRAY)
|
|
{
|
|
wDataType = CIM_FLAG_ARRAY;
|
|
}
|
|
|
|
if(varData.vt == VT_NULL || varData.vt == VT_EMPTY)
|
|
{
|
|
pData = NULL;
|
|
lDataLength = NULL;
|
|
dwStatus = DBSTATUS_S_ISNULL;
|
|
return S_OK;
|
|
}
|
|
|
|
switch(wDataType)
|
|
{
|
|
// Arrays are always shown as ARRAY of VARIANTS to make it easily accessible with scripting
|
|
case CIM_FLAG_ARRAY:
|
|
// if(lOledbType != VT_ARRAY || VT_VARIANT)
|
|
// Bug number 103751 in Windows bugs
|
|
hr = DBSTATUS_E_CANTCONVERTVALUE;
|
|
if(lOledbType == (VT_ARRAY | VT_VARIANT))
|
|
{
|
|
hr = ConvertToVariantArray(((VARIANT *)&varData)->parray,varData.vt,(SAFEARRAY **)&pData);
|
|
}
|
|
bConvert = TRUE;
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
lDataLength = sizeof(DBTIMESTAMP);
|
|
if( varData.bstrVal != NULL)
|
|
{
|
|
// NTRaid:111818
|
|
// 06/13/00
|
|
pSrc = new BYTE[lDataLength];
|
|
|
|
if(pSrc)
|
|
{
|
|
bAlloc = TRUE;
|
|
hr = ConvertDateToOledbType(varData.bstrVal,(DBTIMESTAMP *)pSrc);
|
|
wDataType = DBTYPE_DBTIMESTAMP;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
pSrc = NULL;
|
|
lDataLength = 0;
|
|
bConvert = TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
wDataType = VT_VARIANT;
|
|
lDataLength = sizeof(VARIANT);
|
|
pSrc = (BYTE *)&varData;
|
|
// NTRaid:111818
|
|
// 06/13/00
|
|
hr = S_OK;
|
|
}
|
|
// NTRaid:111818
|
|
// 06/13/00
|
|
if(SUCCEEDED(hr) && bConvert == FALSE && pSrc != NULL && g_pIDataConvert->CanConvert((DBTYPE)wDataType,(DBTYPE)lOledbType) == S_OK)
|
|
{
|
|
//AllocateData(lOledbType,pDst,dwDstLength);
|
|
|
|
if(wDataType == VT_BSTR)
|
|
pDst = *(BSTR **)pData;
|
|
else
|
|
pDst = (void *)pData;
|
|
|
|
hr = g_pIDataConvert->DataConvert( (DBTYPE)wDataType,(DBTYPE)lOledbType, lDataLength,&dbDstLen, pSrc,
|
|
pDst, dbDstLen, 0, &dwStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
|
|
if( hr == S_OK)
|
|
{
|
|
pData = (BYTE *)pDst;
|
|
}
|
|
}
|
|
|
|
if(bAlloc == TRUE)
|
|
{
|
|
delete [] pSrc;
|
|
}
|
|
|
|
lDataLength = (LONG)dbDstLen;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to convert the data to variant type
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertVariantType(VARIANT &varSrc, VARIANT varDst ,CIMTYPE lDstType)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
switch(lDstType)
|
|
{
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
case DBTYPE_DATE:
|
|
case DBTYPE_DBTIME:
|
|
lDstType = DBTYPE_BSTR;
|
|
break;
|
|
|
|
case CIM_REFERENCE :
|
|
case CIM_CHAR16:
|
|
case CIM_OBJECT:
|
|
case CIM_FLAG_ARRAY:
|
|
break;
|
|
|
|
case CIM_UINT64:
|
|
case CIM_SINT64:
|
|
lDstType = VT_R8;
|
|
};
|
|
|
|
hr = VariantChangeType(&varSrc,&varDst,0,(SHORT)lDstType);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to compare data of same types and check if both are same
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CDataMap::CompareData(DWORD dwType,void * pData1 , void *pData2)
|
|
{
|
|
|
|
BOOL bRet = FALSE;
|
|
long lType = VT_NULL;
|
|
|
|
if(pData1 == NULL || pData2 == NULL)
|
|
{
|
|
if(pData1 == pData2)
|
|
bRet = TRUE;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// If the type is of some array
|
|
if (dwType & VT_ARRAY)
|
|
{
|
|
lType = CIM_FLAG_ARRAY;
|
|
}
|
|
else
|
|
lType = dwType;
|
|
|
|
switch( lType ){
|
|
|
|
case VT_NULL:
|
|
case VT_EMPTY:
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case CIM_FLAG_ARRAY:
|
|
bRet = FALSE;
|
|
break;
|
|
|
|
case CIM_SINT8:
|
|
case CIM_UINT8:
|
|
if(!memcmp(pData1,pData2,1))
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case CIM_CHAR16:
|
|
case CIM_SINT16:
|
|
case CIM_UINT16:
|
|
case CIM_BOOLEAN:
|
|
if(!memcmp(pData1,pData2,2))
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case CIM_SINT32:
|
|
case CIM_UINT32:
|
|
case CIM_REAL32:
|
|
if(!memcmp(pData1,pData2,4))
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_REAL64:
|
|
if(!memcmp(pData1,pData2,8))
|
|
bRet = TRUE;
|
|
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
if(!memcmp(pData1,pData2,sizeof(DBTIMESTAMP)))
|
|
bRet = TRUE;
|
|
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
|
|
|
|
if( pData1 != NULL && pData2 != NULL)
|
|
{
|
|
if(!_wcsicmp((WCHAR *)pData1,(WCHAR *)pData2))
|
|
bRet = TRUE;
|
|
}
|
|
|
|
break;
|
|
|
|
case CIM_REFERENCE:
|
|
case CIM_OBJECT:
|
|
case VT_VARIANT:
|
|
case CIM_IUNKNOWN:
|
|
break;
|
|
|
|
|
|
case DBTYPE_DATE:
|
|
if(!memcmp(pData1,pData2,sizeof(DATE)))
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to check if a Safearray is Empty or not
|
|
// NOTE :Works on Single dimensional array
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CDataMap::IsSafeArrayEmpty(SAFEARRAY *psa)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
long lUBound = 0,lLBound = 0;
|
|
HRESULT hr = 0;
|
|
|
|
hr = SafeArrayGetUBound(psa,1,&lUBound);
|
|
hr = SafeArrayGetLBound(psa,1,&lLBound);
|
|
|
|
if( hr == S_OK && lLBound <= lUBound)
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to convert a safearray of one type to safearray of another type if,
|
|
// the source and destination arrays are of different type
|
|
// and this will just copy the safearray to the destination if the arraytypes are of same type
|
|
// NOTE: Works on Single dimensional array
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertAndCopyArray(SAFEARRAY *psaSrc, SAFEARRAY **ppsaDst, DBTYPE dwSrcType,DBTYPE dwDstType,DBSTATUS *pdwStatus)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SAFEARRAYBOUND sabound;
|
|
LONG lUBound = 0;
|
|
LONG lLBound = 0;
|
|
int nArrayIndex = 0;
|
|
void * pSrc = NULL;
|
|
void * pDst = NULL;
|
|
void * pTemp = NULL;
|
|
DBLENGTH dbSrcLen = 0;
|
|
DBLENGTH dbDstLen = 0;
|
|
BSTR * pTempStr;
|
|
BYTE * pbTemp = NULL;
|
|
|
|
short dwSrcElemType = (SHORT) dwSrcType & ~DBTYPE_ARRAY;
|
|
short dwDstElemType = (SHORT)dwDstType & ~DBTYPE_ARRAY;
|
|
|
|
*pdwStatus = DBSTATUS_S_OK;
|
|
|
|
// If the array is not a single dimenstion array , then there is an error
|
|
if(SafeArrayGetDim(psaSrc) != 1)
|
|
return E_FAIL; // Bad array, or too many dimensions
|
|
|
|
// If the source safearray is not empty
|
|
if(!IsSafeArrayEmpty(psaSrc))
|
|
{
|
|
// if source and destination safe array is same then we can
|
|
// copy the safearray using SafeArrayCopy
|
|
if( dwSrcType != dwDstType)
|
|
{
|
|
// if the destination type is array of DBDATETIME then
|
|
// set error and status
|
|
if( IsDateType(dwDstType) && dwDstElemType == DBTYPE_DBTIMESTAMP)
|
|
{
|
|
hr = E_FAIL;
|
|
*pdwStatus = DBSTATUS_E_BADSTATUS;
|
|
}
|
|
else
|
|
// If the data type of the elements of the array can be converted
|
|
// if the source type is date then conversion will be from the string in CIMDATE formate
|
|
// which will be done by a utility function and not from the OLEDB conversion routine
|
|
if( SUCCEEDED (hr = g_pIDataConvert->CanConvert(dwSrcElemType, dwDstElemType)) || IsDateType(dwSrcElemType))
|
|
{
|
|
dbSrcLen = SafeArrayGetElemsize(psaSrc);
|
|
memset(&sabound,0,sizeof(SAFEARRAYBOUND));
|
|
|
|
hr = SafeArrayGetUBound(psaSrc,1,&lUBound);
|
|
hr = SafeArrayGetLBound(psaSrc,1,&lLBound);
|
|
if( lUBound > lLBound)
|
|
{
|
|
sabound.lLbound = lLBound;
|
|
sabound.cElements = lUBound - lLBound +1;
|
|
|
|
// Create the safearray
|
|
*ppsaDst = SafeArrayCreate(dwDstElemType, 1, &sabound);
|
|
pSrc = new BYTE[dbSrcLen];
|
|
if(SUCCEEDED(hr = AllocateData(dwDstElemType,pDst,dbDstLen)))
|
|
{
|
|
if(dwDstElemType == VT_BSTR)
|
|
pTemp = *(BSTR **)pDst;
|
|
else
|
|
pTemp = pDst;
|
|
|
|
|
|
// Navigate thru each element in the dimension of the array
|
|
for(nArrayIndex = lLBound ; nArrayIndex <= lUBound ; nArrayIndex++)
|
|
{
|
|
hr = SafeArrayGetElement(psaSrc,(long *)&nArrayIndex,pSrc);
|
|
if(hr == S_OK && dbDstLen > 0)
|
|
{
|
|
if( IsDateType(dwSrcType) || IsDateType(dwDstType))
|
|
{
|
|
// Convert the element data
|
|
hr = ConvertDateTypes(
|
|
dwSrcElemType,
|
|
dwDstElemType,
|
|
dbSrcLen,
|
|
&dbDstLen,
|
|
&(((VARIANT *)pSrc)->bstrVal),
|
|
pTemp,
|
|
dbDstLen,
|
|
pdwStatus);
|
|
}
|
|
else
|
|
{
|
|
// Free the previous string allocated from previous
|
|
// conversion
|
|
if( dwDstElemType == VT_BSTR && pDst != NULL)
|
|
{
|
|
pTempStr = *(BSTR **)pDst;
|
|
SysFreeString(*pTempStr);
|
|
}
|
|
|
|
|
|
// Convert the element data
|
|
hr = g_pIDataConvert->DataConvert(
|
|
dwSrcElemType,
|
|
dwDstElemType,
|
|
dbSrcLen,
|
|
&dbDstLen,
|
|
pSrc,
|
|
pTemp,
|
|
dbDstLen,
|
|
0,
|
|
pdwStatus,
|
|
0,
|
|
0,
|
|
DBDATACONVERT_DEFAULT);
|
|
|
|
if(hr == DB_E_UNSUPPORTEDCONVERSION && pdwStatus != NULL)
|
|
*pdwStatus = DBSTATUS_E_CANTCONVERTVALUE;
|
|
}
|
|
|
|
// Put the data to the destination array
|
|
hr = SafeArrayPutElement(*ppsaDst,(long *)&nArrayIndex,pTemp);
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
*pdwStatus = DBSTATUS_E_BADSTATUS;
|
|
break;
|
|
}
|
|
}// for
|
|
|
|
}
|
|
}
|
|
|
|
SAFE_DELETE_ARRAY(pSrc);
|
|
pbTemp = (BYTE *)pDst;
|
|
FreeData(dwDstElemType,pbTemp);
|
|
pDst = pbTemp;
|
|
}
|
|
else // Else if the data types of src and dst is not convertible then set the status
|
|
{
|
|
*pdwStatus = DBSTATUS_E_CANTCONVERTVALUE;
|
|
}
|
|
}
|
|
else // if the src and dst or of same type then just copy the arrays
|
|
{
|
|
hr = SafeArrayCopy(psaSrc,ppsaDst);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
ppsaDst = NULL;
|
|
*pdwStatus = DBSTATUS_S_ISNULL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to allocate memory
|
|
// Used by ConvertAndCopyArray function to allocate data for elements for converting
|
|
// the data type and putting it to the array
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::AllocateData(DBTYPE dwType,void *& pData,DBLENGTH &dwLength)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
long lType = dwType;
|
|
SAFEARRAY *pArray = NULL;
|
|
dwLength = 0;
|
|
|
|
// If the type is of some array
|
|
if (lType & CIM_FLAG_ARRAY)
|
|
{
|
|
lType = CIM_FLAG_ARRAY;
|
|
}
|
|
|
|
try
|
|
{
|
|
switch( lType ){
|
|
|
|
case VT_NULL:
|
|
pData = NULL;
|
|
hr = DBSTATUS_S_ISNULL;
|
|
break;
|
|
|
|
case VT_EMPTY:
|
|
pData = NULL;
|
|
hr = DBSTATUS_S_ISNULL;
|
|
break;
|
|
|
|
case CIM_FLAG_ARRAY:
|
|
break;
|
|
|
|
case CIM_SINT8:
|
|
case CIM_UINT8:
|
|
pData = new BYTE[1];
|
|
dwLength = sizeof(BYTE);
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_CHAR16:
|
|
case CIM_SINT16:
|
|
case CIM_UINT16:
|
|
case CIM_BOOLEAN:
|
|
dwLength = sizeof(short);
|
|
pData = new BYTE[dwLength];
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_SINT32:
|
|
case CIM_UINT32:
|
|
case CIM_REAL32:
|
|
dwLength = sizeof(long);
|
|
pData = new BYTE[dwLength];
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_REAL64:
|
|
dwLength = 8;
|
|
pData = new BYTE[8];
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_DATETIME:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
dwLength = sizeof(DBTIMESTAMP);
|
|
pData = new BYTE[dwLength];
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case DBTYPE_DATE:
|
|
dwLength = sizeof(DATE);
|
|
pData = new BYTE[dwLength];
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
pData = new BYTE[sizeof(BSTR)];
|
|
dwLength = sizeof(BSTR);
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
break;
|
|
|
|
case CIM_REFERENCE:
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
break;
|
|
|
|
case VT_VARIANT:
|
|
dwLength = sizeof(VARIANT);
|
|
pData = new BYTE[sizeof(VARIANT)];
|
|
if(!pData)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
VariantInit((VARIANT *)pData);
|
|
}
|
|
break;
|
|
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
// assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
|
|
}
|
|
} // try
|
|
catch(...)
|
|
{
|
|
SAFE_DELETE_ARRAY(pData);
|
|
throw;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to convert WMI (DMTF) formate date to OLEDB format
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertDateToOledbType(BSTR strDate,DBTIMESTAMP *pTimeStamp)
|
|
{
|
|
|
|
WBEMTime wbemTime(strDate);
|
|
if(wbemTime.IsOk())
|
|
{
|
|
SYSTEMTIME sysTime;
|
|
memset(&sysTime,0,sizeof(SYSTEMTIME));
|
|
|
|
wbemTime.GetSYSTEMTIME(&sysTime);
|
|
|
|
pTimeStamp->year = (SHORT) sysTime.wYear;
|
|
pTimeStamp->month = (USHORT)sysTime.wMonth;
|
|
pTimeStamp->day = (USHORT)sysTime.wDay;
|
|
pTimeStamp->hour = (USHORT)sysTime.wHour;
|
|
pTimeStamp->minute = (USHORT)sysTime.wMinute;
|
|
pTimeStamp->second = (USHORT)sysTime.wSecond;
|
|
pTimeStamp->fraction= (ULONG)sysTime.wMilliseconds * 1000000; // converting into billionth of second
|
|
|
|
return S_OK;
|
|
}
|
|
return DBSTATUS_E_CANTCONVERTVALUE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to convert VARIANT date format to OLEDB format
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertVariantDateOledbDate(DATE *pDate,DBTIMESTAMP *pTimeStamp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwDstStatus = 0 ,cbDstMaxLength = 0;
|
|
DBLENGTH dbDstLen = 0;
|
|
|
|
hr = g_pIDataConvert->DataConvert( VT_DATE, DBTYPE_DBTIMESTAMP, sizeof(DATE), &dbDstLen, pDate,
|
|
pTimeStamp, sizeof(DBTIMESTAMP), 0, &dwDstStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to convert OLEDB format to WMI (DMTF) format
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertOledbDateToCIMType(DBTIMESTAMP *pTimeStamp,BSTR &strDate)
|
|
{
|
|
WBEMTime wbemTime;
|
|
SYSTEMTIME sysTime;
|
|
memset(&sysTime,0,sizeof(SYSTEMTIME));
|
|
|
|
sysTime.wYear = pTimeStamp->year;
|
|
sysTime.wMonth = pTimeStamp->month;
|
|
sysTime.wDay = pTimeStamp->day;
|
|
sysTime.wHour = pTimeStamp->hour;
|
|
sysTime.wMinute = pTimeStamp->minute;
|
|
sysTime.wSecond = pTimeStamp->second;
|
|
sysTime.wMilliseconds = (WORD)pTimeStamp->fraction/ 1000000; // converting into micosecond
|
|
|
|
wbemTime = sysTime;
|
|
strDate = wbemTime.GetDMTF();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CDataMap::ConvertOledbDateToCIMType(VARIANT *vTimeStamp,BSTR &strDate)
|
|
{
|
|
WBEMTime wbemTime;
|
|
SYSTEMTIME sysTime;
|
|
memset(&sysTime,0,sizeof(SYSTEMTIME));
|
|
DBTIMESTAMP *pTimeStamp;
|
|
|
|
assert(vTimeStamp->vt == (VT_ARRAY | VT_UI1) || vTimeStamp->vt == (VT_ARRAY | VT_I1));
|
|
|
|
SafeArrayAccessData(vTimeStamp->parray,(void **)&pTimeStamp);
|
|
|
|
ConvertOledbDateToCIMType(pTimeStamp,strDate);
|
|
SafeArrayUnaccessData(vTimeStamp->parray);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to convert OLEDB format to WMI (DMTF) format
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertVariantDateToCIMType(DATE *pDate,BSTR &strDate)
|
|
{
|
|
|
|
DBTIMESTAMP dbTimeStamp;
|
|
|
|
memset(&dbTimeStamp,0,sizeof(DBTIMESTAMP));
|
|
ConvertVariantDateOledbDate(pDate,&dbTimeStamp);
|
|
ConvertOledbDateToCIMType(&dbTimeStamp,strDate);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Check if the DTIMESTAMP passed is valid or not
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CDataMap::IsValidDBTimeStamp(DBTIMESTAMP *pTimeStamp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwDstStatus = 0 , cbDstMaxLength = 0;
|
|
void *pSrc = NULL;
|
|
CVARIANT varDate;
|
|
DBLENGTH dbDstLen = 0;
|
|
|
|
hr = g_pIDataConvert->DataConvert( DBTYPE_DBTIMESTAMP, VT_VARIANT, sizeof(DBTIMESTAMP), &dbDstLen, pTimeStamp,
|
|
&varDate, sizeof(VARIANT), 0, &dwDstStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
|
|
|
|
if( hr != S_OK)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
BOOL CDataMap::IsDateType(DWORD dwType)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if(dwType & VT_ARRAY)
|
|
dwType = dwType & ~(VT_ARRAY);
|
|
|
|
switch(dwType)
|
|
{
|
|
case DBTYPE_DATE:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
case DBTYPE_DBTIME:
|
|
case CIM_DATETIME:
|
|
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
HRESULT CDataMap::ConvertDateTypes( DWORD dwSrcType,
|
|
DWORD dwDstType,
|
|
DBLENGTH dwSrcLen,
|
|
DBLENGTH* pdwDstLen,
|
|
void * pSrc,
|
|
void * & pDst,
|
|
DBLENGTH dbDstLen,
|
|
DWORD * pdwStatus)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBTIMESTAMP *pSrcTimeStamp = NULL;
|
|
|
|
|
|
pSrcTimeStamp = new DBTIMESTAMP;
|
|
// NTRaid:111817
|
|
// 06/07/00
|
|
if(!pSrcTimeStamp)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
memset(pSrcTimeStamp,0,sizeof(DBTIMESTAMP));
|
|
|
|
switch(dwSrcType)
|
|
{
|
|
case CIM_DATETIME:
|
|
hr = ConvertDateToOledbType(*(BSTR*)pSrc ,pSrcTimeStamp);
|
|
break;
|
|
|
|
default :
|
|
hr = g_pIDataConvert->DataConvert( (USHORT)dwSrcType , DBTYPE_DBTIMESTAMP, dwSrcLen, &dbDstLen, pSrc, pSrcTimeStamp,
|
|
sizeof(DBTIMESTAMP), 0, pdwStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
|
|
}
|
|
|
|
if( hr == S_OK)
|
|
{
|
|
switch(dwDstType)
|
|
{
|
|
case CIM_DATETIME:
|
|
hr = ConvertOledbDateToCIMType(pSrcTimeStamp,(BSTR)*(BSTR *)pDst);
|
|
|
|
default:
|
|
hr = g_pIDataConvert->DataConvert( DBTYPE_DBTIMESTAMP, (USHORT)dwDstType, sizeof(DBTIMESTAMP), &dbDstLen, pSrcTimeStamp,
|
|
pDst, dbDstLen, 0, pdwStatus,
|
|
0, // bPrecision for conversion to DBNUMERIC
|
|
0, // bScale for conversion to DBNUMERIC
|
|
DBDATACONVERT_DEFAULT);
|
|
}
|
|
}
|
|
|
|
SAFE_DELETE_PTR(pSrcTimeStamp);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Clear data for a particular DBTYPE
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ClearData(DBTYPE lType, void * pData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
VARIANT *pVar = NULL;
|
|
BSTR * pStr;;
|
|
|
|
//=======================================================================
|
|
// See if it is an array
|
|
//=======================================================================
|
|
// If the pointer sent is not NULL
|
|
if( lType & CIM_FLAG_ARRAY )
|
|
{
|
|
lType = CIM_FLAG_ARRAY;
|
|
}
|
|
|
|
if(pData)
|
|
{
|
|
switch( lType ){
|
|
|
|
case DBTYPE_EMPTY:
|
|
break;
|
|
|
|
case DBTYPE_NULL:
|
|
break;
|
|
|
|
case DBTYPE_ARRAY:
|
|
pVar = (VARIANT *)pData;
|
|
hr = SafeArrayDestroy((SAFEARRAY *)pData);
|
|
break;
|
|
|
|
case DBTYPE_I1:
|
|
case DBTYPE_UI1:
|
|
memset(pData,0,sizeof(BYTE));
|
|
break;
|
|
|
|
case DBTYPE_BOOL:
|
|
case DBTYPE_I2:
|
|
case DBTYPE_UI2:
|
|
memset(pData,0,sizeof(short));
|
|
break;
|
|
|
|
case DBTYPE_R4:
|
|
case DBTYPE_UI4:
|
|
case DBTYPE_I4:
|
|
memset(pData,0,sizeof(long));
|
|
break;
|
|
|
|
case DBTYPE_R8:
|
|
case DBTYPE_I8:
|
|
case DBTYPE_UI8:
|
|
memset(pData,0,8);
|
|
break;
|
|
|
|
case DBTYPE_DBTIMESTAMP:
|
|
memset(pData,0,sizeof(DBTIMESTAMP));
|
|
break;
|
|
|
|
case DBTYPE_BSTR:
|
|
pStr = (BSTR *)pData;
|
|
SysFreeString(*pStr);
|
|
break;
|
|
|
|
case DBTYPE_STR:
|
|
wcscpy((WCHAR *)pData,L"");
|
|
|
|
|
|
case DBTYPE_VARIANT:
|
|
hr = VariantClear((VARIANT *)pData);
|
|
break;
|
|
|
|
case DBTYPE_DATE:
|
|
memset(pData,0,sizeof(DATE));
|
|
break;
|
|
|
|
case DBTYPE_WSTR:
|
|
memset(pData,0,sizeof(WCHAR));
|
|
break;
|
|
|
|
case DBTYPE_IUNKNOWN:
|
|
pData = NULL;
|
|
break;
|
|
|
|
default:
|
|
assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
|
|
}
|
|
}
|
|
if(hr == S_OK)
|
|
pData = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Convert a SAFEARRAY or any type to SAFEARRAY of VARIANT
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataMap::ConvertToVariantArray(SAFEARRAY *pArray,DBTYPE dwSrcType,SAFEARRAY ** ppArrayOut)
|
|
{
|
|
DWORD dwStatus = 0;
|
|
return ConvertAndCopyArray(pArray, ppArrayOut, dwSrcType,VT_ARRAY|VT_VARIANT,&dwStatus);
|
|
}
|