windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/repdrvr/sqlexec.cpp

1016 lines
31 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//***************************************************************************
//
// (c) 1999-2001 by Microsoft Corp. All Rights Reserved.
//
// sqlexec.cpp
//
// cvadai 6-May-1999 created.
//
//***************************************************************************
#define _SQLEXEC_CPP_
#pragma warning( disable : 4786 ) // identifier was truncated to 'number' characters in the
#pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
#include "precomp.h"
#include <std.h>
#include <sqlutils.h>
#include <sqlexec.h>
#include <arena.h>
#include <reputils.h>
#include <smrtptr.h>
#if defined _WIN64
#define ULONG unsigned __int64
#define LONG __int64
#endif
typedef struct tagDBObject
{
HACCESSOR hAcc;
IUnknown *pUnk;
} DBObject;
struct BLOBDATA
{
DBSTATUS dwStatus;
DWORD dwLength;
ISequentialStream* pISeqStream;
};
__int64 CSQLExecute::GetInt64 (DB_NUMERIC *pId)
{
BYTE buff;
__int64 dTemp = 0;
__int64 *pTemp = &dTemp;
int i = 0, iPos = 15;
while (iPos >= 0)
{
buff = pId->val[iPos];
dTemp |= buff;
iPos--;
if (iPos >= 0)
dTemp <<= 8;
}
if (!pId->sign)
dTemp *= -1;
return dTemp;
}
void CSQLExecute::GetInt64 (DB_NUMERIC *pId, wchar_t **ppBuffer)
{
__int64 dTemp;
dTemp = GetInt64 (pId);
wchar_t *pBuff = new wchar_t[21];
if (pBuff)
swprintf(pBuff, L"%I64d", dTemp);
*ppBuffer = pBuff;
}
struct OLEDBDATA
{
DBSTATUS dwStatus;
DWORD dwLen;
BYTE data[8192];
};
//***************************************************************************
void CSQLExecute::SetDBNumeric (DB_NUMERIC &Id, SQL_ID ObjId)
{
Id.precision = 20;
Id.scale = 0;
Id.sign = 1;
__int64 dTemp = ObjId;
short i = 0, iPos = 0;
if (dTemp < 0)
{
Id.sign = 0;
dTemp *= -1;
}
while (iPos < 16)
{
if (!dTemp)
{
Id.val[iPos] = 0;
}
else
{
i = dTemp & 0xFF;
Id.val[iPos] = i;
dTemp >>= 8;
}
iPos++;
}
}
void CSQLExecute::ClearBindingInfo(DBBINDING *binding)
{
binding->obLength = 0;
binding->obStatus = 0;
binding->pTypeInfo = NULL;
binding->pObject = NULL;
binding->pBindExt = NULL;
binding->dwPart = DBPART_VALUE;
binding->dwMemOwner = DBMEMOWNER_CLIENTOWNED;
binding->dwFlags = 0;
binding->bScale = 0;
}
void CSQLExecute::SetBindingInfo(DBBINDING *binding, unsigned long iOrdinal, unsigned long uSize, DBPARAMIO io,
unsigned long maxlen, DBTYPE type, BYTE bPrecision)
{
binding->iOrdinal = iOrdinal;
binding->obValue = uSize;
binding->eParamIO = io;
binding->cbMaxLen = maxlen;
binding->wType = type;
binding->bPrecision = bPrecision;
}
void CSQLExecute::SetParamBindInfo (DBPARAMBINDINFO &BindInfo, LPWSTR pszType, LPWSTR lpName, unsigned long uSize, DWORD dwFlags, BYTE bPrecision)
{
BindInfo.pwszDataSourceType = pszType;
BindInfo.pwszName = lpName;
BindInfo.ulParamSize = uSize;
BindInfo.dwFlags = dwFlags;
BindInfo.bPrecision = bPrecision;
BindInfo.bScale = 0;
}
//***************************************************************************
//
// CSQLExecute::ExecuteQuery
//
//***************************************************************************
HRESULT CSQLExecute::ExecuteQuery(IDBCreateCommand *pCmd, LPCWSTR lpSQL, IRowset **ppIRowset, DWORD *dwNumRows, ...)
{
HRESULT hr = WBEM_S_NO_ERROR;
ICommandText *pICommandText = NULL;
IRowset *pIRowset = NULL;
LONG lRows;
va_list argptr;
int iSize = wcslen(lpSQL)+4096;
wchar_t *pSQL = new wchar_t[iSize];
CDeleteMe <wchar_t> r (pSQL);
if (pSQL)
{
va_start(argptr, dwNumRows);
vswprintf(pSQL, lpSQL, argptr);
va_end(argptr);
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pSQL);
ICommand *pICommand = NULL;
pICommandText->QueryInterface(IID_ICommand,
(void **) & pICommand);
CReleaseMe r1 (pICommand);
hr = pICommand->Execute(NULL, IID_IRowset, NULL,
&lRows, (IUnknown**) &pIRowset);
if (FAILED(hr))
{
int i = 0;
hr = GetWMIError(pICommand);
}
else
{
if (ppIRowset)
*ppIRowset = pIRowset;
else if (pIRowset)
pIRowset->Release();
}
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
if (dwNumRows)
*dwNumRows = lRows;
return hr;
}
//***************************************************************************
//
// CSQLExecute::ExecuteQuery
//
//***************************************************************************
HRESULT CSQLExecute::ExecuteQuery(IDBInitialize *pDBInit, LPCWSTR lpSQL, IRowset **ppIRowset, DWORD *dwNumRows)
{
HRESULT hr = WBEM_S_NO_ERROR;
IDBCreateSession *pIDBCreate = NULL;
IDBCreateCommand *pIDBCreateCommand = NULL;
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pIDBCreate);
CReleaseMe r (pIDBCreate);
if (SUCCEEDED(hr))
{
hr = pIDBCreate->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pIDBCreateCommand);
CReleaseMe r2 (pIDBCreateCommand);
if (SUCCEEDED(hr))
{
hr = ExecuteQuery(pIDBCreateCommand, lpSQL, ppIRowset, dwNumRows);
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecute::ExecuteQueryAsync
//
//***************************************************************************
HRESULT CSQLExecute::ExecuteQueryAsync(IDBInitialize *pDBInit, LPCWSTR lpSQL, IDBAsynchStatus **ppIAsync, DWORD *dwNumRows)
{
HRESULT hr = WBEM_S_NO_ERROR;
IDBCreateSession *pIDBCreate = NULL;
IDBCreateCommand *pIDBCreateCommand = NULL;
ICommandText *pICommandText = NULL;
LONG lRows = 0;
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pIDBCreate);
CReleaseMe r (pIDBCreate);
if (SUCCEEDED(hr))
{
hr = pIDBCreate->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pIDBCreateCommand);
CReleaseMe r1 (pIDBCreateCommand);
if (SUCCEEDED(hr))
{
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r2 (pICommandText);
if (SUCCEEDED(hr))
{
// Admittedly, this won't work unless we have
// set the IDBProperties DBPROP_ROWSET_ASYNCH
// property to DBPROPVAL_ASYNCH_INITIALIZE
pICommandText->SetCommandText(DBGUID_DBSQL, lpSQL);
ICommand *pICommand = NULL;
pICommandText->QueryInterface(IID_ICommand,
(void **) & pICommand);
CReleaseMe r3 (pICommand);
hr = pICommand->Execute(NULL, IID_IDBAsynchStatus, NULL,
&lRows, (IUnknown**) ppIAsync);
}
}
}
if (dwNumRows)
*dwNumRows = lRows;
return hr;
}
//***************************************************************************
//
// CSQLExecute::IsDataReady
//
//***************************************************************************
HRESULT CSQLExecute::IsDataReady(IDBAsynchStatus *pIAsync)
{
HRESULT hr = WBEM_S_NO_ERROR;
unsigned long uAsyncPhase = 0;
ULONG uProgress, uProgressMax;
if (pIAsync)
hr = pIAsync->GetStatus(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN,
&uProgress, &uProgressMax, &uAsyncPhase, NULL);
if (SUCCEEDED(hr))
hr = WBEM_S_NO_ERROR;
else if (hr == DB_E_CANCELED)
hr = WBEM_S_OPERATION_CANCELLED;
else
{
hr = WBEM_E_FAILED;
// SetWMIOLEDBError(pIAsync);
}
if (uAsyncPhase == DBASYNCHPHASE_COMPLETE)
hr = WBEM_S_NO_ERROR;
else if (uAsyncPhase == DBASYNCHPHASE_INITIALIZATION ||
uAsyncPhase == DBASYNCHPHASE_POPULATION)
hr = WBEM_S_PENDING;
return hr;
}
//***************************************************************************
//
// CSQLExecute::CancelQuery
//
//***************************************************************************
HRESULT CSQLExecute::CancelQuery(IDBAsynchStatus *pIAsync)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (pIAsync)
{
hr = pIAsync->Abort(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN);
}
return hr;
}
//***************************************************************************
//
// CSQLExecute::GetNumColumns
//
//***************************************************************************
HRESULT CSQLExecute::GetNumColumns(IRowset *pIRowset, IMalloc *pMalloc, int &iNumCols)
{
HRESULT hr = WBEM_S_NO_ERROR;
DBCOLUMNINFO* pColumnsInfo = NULL;
IColumnsInfo* pIColumnsInfo = NULL;
OLECHAR* pColumnStrings = NULL;
ULONG uNum;
pIRowset->QueryInterface(IID_IColumnsInfo, (void**) &pIColumnsInfo);
CReleaseMe r (pIColumnsInfo);
hr = pIColumnsInfo->GetColumnInfo(&uNum, &pColumnsInfo, &pColumnStrings);
pMalloc->Free( pColumnsInfo );
pMalloc->Free( pColumnStrings );
if (SUCCEEDED(hr))
iNumCols = (int)uNum;
return hr;
}
//***************************************************************************
//
// CSQLExecute::GetDataType
//
//***************************************************************************
HRESULT CSQLExecute::GetDataType(IRowset *pIRowset, int iPos, IMalloc *pMalloc, DWORD &dwType,
DWORD &dwSize, DWORD &dwPrec, DWORD &dwScale, LPWSTR *lpColName)
{
HRESULT hr = WBEM_S_NO_ERROR;
DBCOLUMNINFO* pColumnsInfo = NULL;
IColumnsInfo* pIColumnsInfo = NULL;
OLECHAR* pColumnStrings = NULL;
ULONG uNum;
BYTE* pRowValues = NULL;
pIRowset->QueryInterface(IID_IColumnsInfo, (void**) &pIColumnsInfo);
CReleaseMe r (pIColumnsInfo);
hr = pIColumnsInfo->GetColumnInfo(&uNum, &pColumnsInfo, &pColumnStrings);
if (SUCCEEDED(hr) && uNum >= iPos)
{
dwSize = pColumnsInfo[iPos-1].ulColumnSize;
dwPrec = pColumnsInfo[iPos-1].bPrecision;
dwScale = pColumnsInfo[iPos-1].bScale;
dwType = pColumnsInfo[iPos-1].wType;
if (lpColName)
*lpColName = Macro_CloneLPWSTR(pColumnsInfo[iPos-1].pwszName);
}
else
{
dwType = 0;
dwSize = 0;
dwPrec = 0;
dwScale = 0;
}
pMalloc->Free( pColumnsInfo );
pMalloc->Free( pColumnStrings );
return hr;
}
//***************************************************************************
//
// CSQLExecute::GetColumnValue
//
//***************************************************************************
HRESULT CSQLExecute::GetColumnValue(IRowset *pIRowset, int iPos, IMalloc *pMalloc, HROW **ppRow,
VARIANT &vValue, LPWSTR * lpColName)
{
HRESULT hr = WBEM_S_NO_ERROR;
DWORD dwType;
DWORD dwOrigType ;
IAccessor* pIAccessor=NULL; // Pointer to the
// accessor
HACCESSOR hAccessor; // Accessor handle
HROW *pRows = NULL;
ULONG cRowsObtained; // Count of rows
// obtained
DBBINDSTATUS* pDBBindStatus = NULL;
DBBINDING* pDBBindings = NULL;
OLEDBDATA data;
VariantClear(&vValue);
if (!ppRow)
{
hr = WBEM_E_INVALID_PARAMETER;
}
else
{
if (*ppRow)
{
pRows = *ppRow;
}
else
{
HROW *hRow = new HROW[1];
if (!hRow)
return WBEM_E_OUT_OF_MEMORY;
pRows = &hRow[0];
hr = pIRowset->GetNextRows( 0, // Reserved
0, // cRowsToSkip
1, // cRowsDesired
&cRowsObtained, // cRowsObtained
&pRows ); // Filled in w/ row handles.
if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
{
*ppRow = pRows;
}
}
if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
{
DWORD dwSize = 0, dwPrec = 0, dwScale = 0;
hr = GetDataType(pIRowset, iPos, pMalloc, dwType, dwSize, dwPrec, dwScale, lpColName);
if (SUCCEEDED(hr))
{
dwOrigType = dwType;
if (dwType == DBTYPE_DATE || dwType == DBTYPE_DBDATE)
{
dwType = DBTYPE_DBTIMESTAMP;
dwSize = sizeof(DBTIMESTAMP)+1;
}
else if (dwType == DBTYPE_CY ||
(dwType == DBTYPE_NUMERIC && dwScale > 0) ||
dwType == DBTYPE_GUID)
{
dwType = DBTYPE_WSTR;
dwSize = 100;
}
pDBBindings = new DBBINDING[1];
CDeleteMe <DBBINDING> r5 (pDBBindings);
if (!pDBBindings)
return WBEM_E_OUT_OF_MEMORY;
pDBBindings[0].iOrdinal = iPos;
pDBBindings[0].obValue = offsetof(OLEDBDATA, data);
pDBBindings[0].obLength = offsetof(OLEDBDATA, dwLen);
pDBBindings[0].obStatus = offsetof(OLEDBDATA, dwStatus);
pDBBindings[0].pTypeInfo = NULL;
pDBBindings[0].pObject = NULL;
pDBBindings[0].pBindExt = NULL;
pDBBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
pDBBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
pDBBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
pDBBindings[0].wType = dwType;
if (dwSize > 65535)
dwSize = 65535;
if (dwType == DBTYPE_WSTR ||
dwType == DBTYPE_STR ||
dwType == DBTYPE_BSTR)
pDBBindings[0].cbMaxLen = dwSize+1;
else
pDBBindings[0].cbMaxLen = dwSize;
pDBBindings[0].dwFlags = 0;
pDBBindings[0].bPrecision = dwPrec;
pDBBindings[0].bScale = dwScale;
pDBBindStatus = new DBBINDSTATUS[1];
CDeleteMe <DBBINDSTATUS> r6 (pDBBindStatus);
if (!pDBBindStatus)
return WBEM_E_OUT_OF_MEMORY;
pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
CReleaseMe r7 (pIAccessor);
hr = pIAccessor->CreateAccessor(
DBACCESSOR_ROWDATA,// Accessor will be used to retrieve row
// data
1, // Number of columns being bound
pDBBindings, // Structure containing bind info
0,
&hAccessor, // Returned accessor handle
pDBBindStatus // Information about binding validity
);
if (SUCCEEDED(hr))
{
hr = pIRowset->GetData(*pRows, hAccessor, &data);
VariantClear(&vValue);
if (data.dwStatus != DBSTATUS_S_ISNULL)
SetVariant(dwType, &vValue, data.data, dwOrigType);
else
vValue.vt = VT_NULL;
hr = WBEM_S_NO_ERROR;
}
}
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
if (hr == DB_S_ENDOFROWSET)
hr = WBEM_S_NO_MORE_DATA;
return hr;
}
//***************************************************************************
//
// CSQLExecute::ReadImageValue
//
//***************************************************************************
HRESULT CSQLExecute::ReadImageValue (IRowset *pIRowset, int iPos, HROW **ppRow, BYTE **ppBuffer, DWORD &dwLen)
{
HRESULT hr = WBEM_S_NO_ERROR;
IAccessor* pIAccessor; // Pointer to the
DBOBJECT ObjectStruct;
HACCESSOR hAccessor; // Accessor handle
ULONG cRowsObtained; // Count of rows
// obtained
DBBINDSTATUS* pDBBindStatus = NULL;
DBBINDING *pDBBindings = NULL;
ObjectStruct.dwFlags = STGM_READ;
ObjectStruct.iid = IID_ISequentialStream;
HROW* pRows = NULL;
unsigned long cbRead; // Count of bytes read
BLOBDATA BLOBGetData;
if (!ppRow)
{
hr = WBEM_E_INVALID_PARAMETER;
}
else
{
if (*ppRow)
{
pRows = *ppRow;
}
else
{
HROW *hRow = new HROW[1];
if (!hRow)
return WBEM_E_OUT_OF_MEMORY;
pRows = &hRow[0];
hr = pIRowset->GetNextRows( 0, // Reserved
0, // cRowsToSkip
1, // cRowsDesired
&cRowsObtained, // cRowsObtained
&pRows ); // Filled in w/ row handles.
if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
{
*ppRow = pRows;
}
}
}
dwLen = 0;
if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
{
pDBBindings = new DBBINDING[1];
if (!pDBBindings)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe <DBBINDING> d (pDBBindings);
pDBBindings[0].iOrdinal = iPos;
pDBBindings[0].obValue = offsetof(BLOBDATA, pISeqStream);
pDBBindings[0].obLength = offsetof(BLOBDATA, dwLength);
pDBBindings[0].obStatus = offsetof(BLOBDATA, dwStatus);
pDBBindings[0].pTypeInfo = NULL;
pDBBindings[0].pObject = &ObjectStruct;
pDBBindings[0].pBindExt = NULL;
pDBBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
pDBBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
pDBBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
pDBBindings[0].wType = DBTYPE_IUNKNOWN;
pDBBindings[0].cbMaxLen = 0;
pDBBindings[0].dwFlags = 0;
pDBBindings[0].bPrecision = 0;
pDBBindings[0].bScale = 0;
pDBBindStatus = new DBBINDSTATUS[1];
if (!pDBBindStatus)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe <DBBINDSTATUS> d1 (pDBBindStatus);
pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
CReleaseMe r1 (pIAccessor);
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1,
pDBBindings, 0, &hAccessor, pDBBindStatus);
if (FAILED(hr))
hr = WBEM_E_OUT_OF_MEMORY;
else
{
DWORD dwTotal = 0;
// Get the row data, the pointer to an ISequentialStream*.
hr = pIRowset->GetData(*pRows, hAccessor, &BLOBGetData);
if (SUCCEEDED(hr) && BLOBGetData.dwStatus == DBSTATUS_S_OK)
{
ISequentialStream *pStream = BLOBGetData.pISeqStream;
CReleaseMe r (pStream);
DWORD dwSize = BLOBGetData.dwLength;
BYTE *pbTemp = NULL;
pbTemp = (BYTE *)CWin32DefaultArena::WbemMemAlloc(dwSize);
if (!pbTemp)
{
hr = WBEM_E_OUT_OF_MEMORY;
}
else
{
ZeroMemory(pbTemp, dwSize);
*ppBuffer = pbTemp;
hr = pStream->Read(pbTemp, dwSize, &cbRead);
if (hr == S_OK)
dwLen = cbRead;
else
hr = WBEM_E_FAILED;
}
}
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecute::WriteImageValue
//
//***************************************************************************
HRESULT CSQLExecute::WriteImageValue(IDBCreateCommand *pIDBCreateCommand, LPCWSTR lpSQL, int iPos, BYTE *pValue, DWORD dwLen)
{
HRESULT hr = WBEM_S_NO_ERROR;
IAccessor* pIAccessor; // Pointer to the
DBOBJECT ObjectStruct;
HACCESSOR hAccessor; // Accessor handle
ULONG cRowsObtained; // Count of rows
// obtained
DBBINDSTATUS* pDBBindStatus = NULL;
DBBINDING *pDBBindings = NULL;
HROW* pRows = NULL;
LONG lRows;
ICommandText* pICommandText = NULL;
ICommandProperties* pICommandProperties = NULL;
IRowset *pIRowset = NULL;
IRowsetChange *pRowsetChg = NULL;
ObjectStruct.dwFlags = STGM_READ;
ObjectStruct.iid = IID_ISequentialStream;
BLOBDATA BLOBSetData;
DBPROPSET rgPropSets[1];
DBPROP rgProperties[1];
const ULONG cProperties = 1;
rgPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
rgPropSets[0].cProperties = cProperties;
rgPropSets[0].rgProperties = rgProperties;
//Now set properties in the property group (DBPROPSET_ROWSET)
rgPropSets[0].rgProperties[0].dwPropertyID = DBPROP_UPDATABILITY;
rgPropSets[0].rgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
rgPropSets[0].rgProperties[0].dwStatus = DBPROPSTATUS_OK;
rgPropSets[0].rgProperties[0].colid = DB_NULLID;
rgPropSets[0].rgProperties[0].vValue.vt = VT_I4;
V_I4(&rgPropSets[0].rgProperties[0].vValue) = DBPROPVAL_UP_CHANGE;
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
//Set the rowset properties
hr = pICommandText->QueryInterface(IID_ICommandProperties,
(void **)&pICommandProperties);
CReleaseMe r (pICommandProperties);
if (SUCCEEDED(hr))
{
hr = pICommandProperties->SetProperties(1, rgPropSets);
pICommandText->SetCommandText(DBGUID_DBSQL, lpSQL);
ICommand *pICommand = NULL;
pICommandText->QueryInterface(IID_ICommand,
(void **) & pICommand);
CReleaseMe r2 (pICommand);
hr = pICommand->Execute(NULL, IID_IRowsetChange, NULL,
&lRows, (IUnknown**) &pRowsetChg);
CReleaseMe r3 (pRowsetChg);
if (FAILED(hr))
{
int i = 0;
hr = GetWMIError(pICommand);
}
else
{
hr = pRowsetChg->QueryInterface(IID_IRowset,
(void **)&pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
{
HROW *hRow = new HROW[1];
if (!hRow)
return WBEM_E_OUT_OF_MEMORY;
pRows = &hRow[0];
hr = pIRowset->GetNextRows( 0, // Reserved
0, // cRowsToSkip
1, // cRowsDesired
&cRowsObtained, // cRowsObtained
&pRows ); // Filled in w/ row handles.
CDeleteMe <HROW> d0 (hRow);
if (SUCCEEDED(hr))
{
pDBBindings = new DBBINDING[1];
if (!pDBBindings)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe <DBBINDING> d1 (pDBBindings);
pDBBindings[0].iOrdinal = iPos;
pDBBindings[0].obValue = offsetof(BLOBDATA, pISeqStream);
pDBBindings[0].obLength = offsetof(BLOBDATA, dwLength);
pDBBindings[0].obStatus = offsetof(BLOBDATA, dwStatus);
pDBBindings[0].pTypeInfo = NULL;
pDBBindings[0].pObject = &ObjectStruct;
pDBBindings[0].pBindExt = NULL;
pDBBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
pDBBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
pDBBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
pDBBindings[0].wType = DBTYPE_IUNKNOWN;
pDBBindings[0].cbMaxLen = 0;
pDBBindings[0].dwFlags = 0;
pDBBindings[0].bPrecision = 0;
pDBBindings[0].bScale = 0;
pDBBindStatus = new DBBINDSTATUS[1];
if (!pDBBindStatus)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe <DBBINDSTATUS> d2 (pDBBindStatus);
hr = pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
CReleaseMe r5 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1,
pDBBindings, 0, &hAccessor, pDBBindStatus);
CSeqStream *pSeqStream = new CSeqStream;
if (!pSeqStream)
return WBEM_E_OUT_OF_MEMORY;
pSeqStream->Write(pValue, dwLen, NULL);
BLOBSetData.pISeqStream = pSeqStream;
BLOBSetData.dwStatus = DBSTATUS_S_OK;
BLOBSetData.dwLength = pSeqStream->Length();
hr = pRowsetChg->SetData(pRows[0], hAccessor, &BLOBSetData);
if (FAILED(hr))
hr = GetWMIError(pICommand);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
pIRowset->ReleaseRows(1, pRows, NULL, NULL, NULL);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecute::SetVariant
//
//***************************************************************************
void CSQLExecute::SetVariant(DWORD dwType, VARIANT *vValue, BYTE *pData, DWORD dwTargetType)
{
vValue->vt = VT_NULL;
BYTE *pBuffer = NULL;
wchar_t *wTemp = NULL;
switch(dwType)
{
case DBTYPE_DBTIMESTAMP:
if (*pData)
{
DBTIMESTAMP *pTime = ((DBTIMESTAMP *)pData);
wchar_t szTmp[100];
swprintf(szTmp, L"%04d%02d%02d%02d%02d%02d.%06d+000",
pTime->year, pTime->month, pTime->day, pTime->hour,
pTime->minute, pTime->second, pTime->fraction);
V_BSTR(vValue) = SysAllocString((LPWSTR)szTmp);
vValue->vt = VT_BSTR;
}
break;
case DBTYPE_STR:
wTemp = new wchar_t[(strlen((const char *)pData)*2)];
if (wTemp)
{
swprintf(wTemp, L"%S", (const char *)pData);
V_BSTR(vValue) = SysAllocString(wTemp);
vValue->vt = VT_BSTR;
delete wTemp;
}
break;
case DBTYPE_WSTR:
case DBTYPE_BSTR:
V_BSTR(vValue) = SysAllocString((LPWSTR)pData);
vValue->vt = VT_BSTR;
break;
case DBTYPE_I4:
case DBTYPE_UI4:
if (*((long *)pData) != NULL)
V_I4(vValue) = *((long *)pData);
else
V_I4(vValue) = 0;
vValue->vt = VT_I4;
break;
case DBTYPE_I2:
case DBTYPE_UI2:
if (*((short *)pData) != NULL)
V_I4(vValue) = *((short *)pData);
else
V_I4(vValue) = 0;
vValue->vt = VT_I4; // We are expecting the short ints to come out as long...
break;
case DBTYPE_I1:
case DBTYPE_UI1:
V_UI1(vValue) = *((BYTE *)pData);
vValue->vt = VT_UI1;
break;
case DBTYPE_BOOL:
V_BOOL(vValue) = (*((BOOL *)pData) ? TRUE: FALSE);
vValue->vt = VT_BOOL;
break;
case DBTYPE_R4:
if (*((float *)pData) != NULL)
{
vValue->fltVal = (*((float *)pData));
}
else
vValue->fltVal = 0;
vValue->vt = VT_R4;
break;
case DBTYPE_R8:
if (*((double *)pData) != NULL)
{
vValue->dblVal = (*((double *)pData));
}
else
vValue->dblVal = 0;
vValue->vt = VT_R8;
break;
case DBTYPE_I8:
case DBTYPE_UI8:
case DBTYPE_NUMERIC:
if (*pData != NULL)
{
wchar_t *pwTemp = NULL;
long lRet;
short sRet;
BYTE bRet;
DB_NUMERIC *pTemp = ((DB_NUMERIC *)pData);
switch(dwTargetType)
{
case DBTYPE_I8:
case DBTYPE_UI8:
case DBTYPE_NUMERIC:
GetInt64(pTemp, &pwTemp);
vValue->bstrVal = SysAllocString(pwTemp);
vValue->vt = VT_BSTR;
delete pwTemp;
break;
case DBTYPE_I4:
case DBTYPE_UI2:
case DBTYPE_UI4:
lRet = (*((long *)pTemp->val));
vValue->lVal = lRet;
if (!pTemp->sign) vValue->lVal *= -1;
vValue->vt = VT_I4;
break;
case DBTYPE_I2:
sRet = *((short *)pTemp->val);
V_I2(vValue) = sRet;
vValue->vt = VT_I2;
if (!pTemp->sign) V_I2(vValue) *= -1;
break;
case CIM_BOOLEAN:
V_BOOL(vValue) = *((BOOL *)pTemp->val)?true:false;
vValue->vt = VT_BOOL;
break;
case DBTYPE_UI1:
case DBTYPE_I1:
case CIM_CHAR16:
bRet = *((BYTE *)pTemp->val);
V_UI1(vValue) = bRet;
vValue->vt = VT_UI1;
break;
}
}
break;
case DBTYPE_BYTES:
// UINT8|ARRAY
// We have to set this as an array of bytes.
// vValue->pbVal = (BYTE *)pData;
// vValue->vt = VT_UI1|VT_ARRAY; // ?? Is this right? TBD
break;
}
}