windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/oledb/dataconvert.cpp
2020-09-26 16:20:57 +08:00

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);
}