2025-04-27 07:49:33 -04:00

5502 lines
226 KiB
C++

//***************************************************************************
//
// (c) 1999-2001 by Microsoft Corp. All Rights Reserved.
//
// SQLPROCS.cpp
//
// cvadai 6-May-1999 created.
//
//***************************************************************************
#define _SQL_PROCS_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"
#define DBINITCONSTANTS
#include <std.h>
#include <sqlutils.h>
#include <sqlexec.h>
#include <crepdrvr.h>
#include <sqloledb.h>
#include <repdrvr.h>
#include <wbemint.h>
#include <math.h>
#include <objbase.h>
#include <resource.h>
#include <reputils.h>
#include <sqlcache.h>
#include <arena.h>
#include <crc64.h>
#include <smrtptr.h>
#include <sqlit.h>
#if defined _WIN64
#define ULONG unsigned __int64
#define LONG __int64
#endif
BSTR OLEDBTruncateLongText(const wchar_t *pszData, long lMaxLen, bool &bChg,
int iTruncLen=REPDRVR_MAX_LONG_STRING_SIZE, BOOL bAppend=TRUE)
{
BSTR sRet = NULL;
bChg = false;
if (!pszData)
return SysAllocString(L"");
long lLen = wcslen(pszData);
if (lLen <= lMaxLen)
return SysAllocString(pszData);
wchar_t *wTemp = new wchar_t [iTruncLen+1];
if (wTemp)
{
if (bAppend)
{
wcsncpy(wTemp, pszData, iTruncLen-3);
wTemp[iTruncLen-3] = L'\0';
wcscat(wTemp, L"...\0");
}
else
{
wcsncpy(wTemp, pszData, iTruncLen);
wTemp[iTruncLen] = L'\0';
}
bChg = true;
sRet = SysAllocString(wTemp);
delete wTemp;
}
return sRet;
}
//***************************************************************************
//
// CWmiDbController::GetLogonTemplate
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiDbController::GetLogonTemplate(
/* [in] */ LCID lLocale,
/* [in] */ DWORD dwFlags,
/* [out] */ WMIDB_LOGON_TEMPLATE __RPC_FAR *__RPC_FAR *ppTemplate)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (dwFlags != 0 || !ppTemplate)
return WBEM_E_INVALID_PARAMETER;
try
{
if (!m_pIMalloc)
{
hr = CoGetMalloc(MEMCTX_TASK, &m_pIMalloc);
if (FAILED(hr))
return hr;
}
if (ppTemplate)
{
WMIDB_LOGON_TEMPLATE *pTemp = new WMIDB_LOGON_TEMPLATE;
if (!pTemp)
return WBEM_E_OUT_OF_MEMORY;
pTemp->dwArraySize = 5;
if (pTemp)
{
HINSTANCE hRCDll = GetResourceDll(lLocale);
if (!hRCDll)
{
LCID lTemp = GetUserDefaultLangID();
hRCDll = GetResourceDll(lTemp);
if (!hRCDll)
{
lTemp = GetSystemDefaultLangID();
hRCDll = GetResourceDll(lTemp);
if (!hRCDll)
hRCDll = LoadLibrary(L"reprc.dll"); // Last resort - try the current directory.
}
}
wchar_t wDB[101], wUser[101], wPwd[101], wLocale[101], wServer[101];
pTemp->pParm = new WMIDB_LOGON_PARAMETER[5];
if (!pTemp->pParm)
{
delete pTemp;
return WBEM_E_OUT_OF_MEMORY;
}
if (hRCDll)
{
LoadString(hRCDll, IDS_WMI_DATABASE, wDB, 100);
LoadString(hRCDll, IDS_WMI_USER_NAME, wUser, 100);
LoadString(hRCDll, IDS_WMI_PASSWORD, wPwd, 100);
LoadString(hRCDll, IDS_WMI_LOCALE, wLocale, 100);
LoadString(hRCDll, IDS_WMI_SERVER, wServer, 100);
FreeLibrary(hRCDll);
}
else
{
wcscpy(wDB, L"Database");
wcscpy(wUser, L"UserID");
wcscpy(wPwd, L"Password");
wcscpy(wLocale, L"Locale");
wcscpy(wServer, L"Server");
}
pTemp->pParm[0].dwId = DBPROP_INIT_DATASOURCE;
pTemp->pParm[0].strParmDisplayName = SysAllocString(wServer);
VariantInit(&(pTemp->pParm[0].Value));
pTemp->pParm[1].dwId = DBPROP_AUTH_USERID;
pTemp->pParm[1].strParmDisplayName = SysAllocString(wUser);
VariantInit(&(pTemp->pParm[1].Value));
pTemp->pParm[2].dwId = DBPROP_AUTH_PASSWORD;
pTemp->pParm[2].strParmDisplayName = SysAllocString(wPwd);
VariantInit(&(pTemp->pParm[2].Value));
pTemp->pParm[3].dwId = DBPROP_INIT_LOCATION;
pTemp->pParm[3].strParmDisplayName = SysAllocString(wDB);
VariantInit(&(pTemp->pParm[3].Value));
pTemp->pParm[4].dwId = DBPROP_INIT_LCID;
pTemp->pParm[4].strParmDisplayName = SysAllocString(wLocale);
VariantInit(&(pTemp->pParm[4].Value));
pTemp->pParm[4].Value.lVal = lLocale;
pTemp->pParm[4].Value.vt = VT_I4;
*ppTemplate = pTemp;
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else
hr = WBEM_E_INVALID_PARAMETER;
}
catch (...)
{
ERRORTRACE((LOG_WBEMCORE, "Fatal error in CWmiDbController::GetLogonTemplate"));
hr = WBEM_E_CRITICAL_ERROR;
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::InsertArray
//
//***************************************************************************
HRESULT CWmiDbSession::InsertArray(CSQLConnection *pConn,IWmiDbHandle *pScope,
SQL_ID dObjectId, SQL_ID dClassId,
DWORD dwPropertyID, VARIANT &vValue, long lFlavor, DWORD dwRefID,
LPCWSTR lpObjectKey , LPCWSTR lpPath , SQL_ID dScope, CIMTYPE ct )
{
HRESULT hr = WBEM_S_NO_ERROR;
IRowset *pIRowset = NULL;
DWORD dwRows = 0;
if (!m_pController ||
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
return WBEM_E_SHUTTING_DOWN;
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
if (vValue.vt == VT_UNKNOWN)
{
BYTE *pBuff = NULL;
DWORD dwLen = 0;
IUnknown *pUnk = V_UNKNOWN (&vValue);
if (pUnk)
{
_IWmiObject *pInt = NULL;
hr = pUnk->QueryInterface(IID__IWmiObject, (void **)&pInt);
if (SUCCEEDED(hr))
{
pInt->GetObjectMemory(NULL, 0, &dwLen);
pBuff = new BYTE [dwLen];
if (pBuff)
{
DWORD dwLen1;
pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
hr = CSQLExecProcedure::InsertBlobData (pConn, dClassId, dObjectId,
dwPropertyID, NULL, 0, 0);
wchar_t wSQL[1024];
swprintf(wSQL, L"select PropertyImageValue from ClassImages where ObjectId = %I64d and PropertyId = %ld",
dObjectId, dwPropertyID);
hr = CSQLExecute::WriteImageValue(pCmd, wSQL, 1, pBuff, dwLen);
delete pBuff;
}
else
hr = WBEM_E_OUT_OF_MEMORY;
pInt->Release();
}
}
}
else if (((vValue.vt & 0xFFF) == VT_UI1) || vValue.vt == VT_BSTR)
{
BYTE *pBuff = NULL;
DWORD dwLen = 0;
// Get the byte buffer out of the safearray.
if ((vValue.vt & 0xFFF) == VT_UI1)
GetByteBuffer(&vValue, &pBuff, dwLen);
else // its a bstr.
{
dwLen = wcslen(vValue.bstrVal)*2;
char * pTemp = new char[dwLen+1];
if (pTemp)
{
sprintf(pTemp, "%S", vValue.bstrVal);
pBuff = (unsigned char *)pTemp;
}
}
if (pBuff)
{
hr = CSQLExecProcedure::InsertBlobData (pConn, dClassId, dObjectId,
dwPropertyID, NULL, 0, 0);
wchar_t wSQL[1024];
swprintf(wSQL, L"select PropertyImageValue from ClassImages where ObjectId = %I64d and PropertyId = %ld",
dObjectId, dwPropertyID);
hr = CSQLExecute::WriteImageValue(pCmd, wSQL, 1, pBuff, dwLen);
delete pBuff;
}
}
else
{
bool bIsQfr = FALSE;
DWORD dwFlags = 0;
SQL_ID dClassID = 0;
DWORD dwStorage = 0;
hr = GetSchemaCache()->GetPropertyInfo (dwPropertyID, NULL, &dClassID, &dwStorage,
NULL, &dwFlags);
bIsQfr = (dwFlags & REPDRVR_FLAG_QUALIFIER) ? TRUE : FALSE;
SAFEARRAY* psaArray = NULL;
psaArray = V_ARRAY(&vValue);
if (psaArray)
{
long i = 0;
int iType = vValue.vt & 0xFF;
VARIANT vTemp;
VariantInit(&vTemp);
long lLBound, lUBound;
SafeArrayGetLBound(psaArray, 1, &lLBound);
SafeArrayGetUBound(psaArray, 1, &lUBound);
lUBound -= lLBound;
lUBound += 1;
InsertQfrValues *pQfr = NULL;
pQfr = new InsertQfrValues[lUBound];
if (!pQfr)
return WBEM_E_OUT_OF_MEMORY;
int iPos = 0;
for (i = 0; i < lUBound; i++)
{
if (iType != CIM_OBJECT)
{
if (iType != VT_NULL && iType != VT_EMPTY)
{
hr = GetVariantFromArray(psaArray, i, iType, vTemp);
LPWSTR lpVal = GetStr(vTemp);
CDeleteMe <wchar_t> r1(lpVal);
VariantClear(&vTemp);
if (FAILED(hr))
break;
//if (wcslen(lpVal))
{
pQfr[iPos].iPos = i;
pQfr[iPos].iQfrID = dwRefID;
pQfr[iPos].iPropID = dwPropertyID;
pQfr[iPos].pRefKey = NULL;
pQfr[iPos].bLong = false;
pQfr[iPos].bIndexed = (dwFlags & (REPDRVR_FLAG_KEY + REPDRVR_FLAG_INDEXED)) ? TRUE : FALSE;
pQfr[iPos].iStorageType = dwStorage;
pQfr[iPos].dClassId = dClassID;
pQfr[iPos].iFlavor = lFlavor;
if (ct == CIM_REFERENCE)
{
pQfr[iPos].bIndexed = TRUE; // References are always keys
LPWSTR lpTemp = NULL;
IWbemPath *pPath = NULL;
hr = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
IID_IWbemPath, (LPVOID *) &pPath);
CReleaseMe r8 (pPath);
if (SUCCEEDED(hr))
{
if (lpVal)
{
pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, lpVal);
hr = NormalizeObjectPathGet(pScope, pPath, &lpTemp, NULL, NULL, NULL, pConn);
CDeleteMe <wchar_t> r1(lpTemp);
if (SUCCEEDED(hr))
{
LPWSTR lpTemp2 = NULL;
lpTemp2 = GetKeyString(lpVal);
CDeleteMe <wchar_t> d (lpTemp2);
pQfr[iPos].pRefKey = new wchar_t [21];
if (pQfr[iPos].pRefKey)
swprintf(pQfr[iPos].pRefKey, L"%I64d", CRC64::GenerateHashValue(lpTemp2));
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else
{
hr = WBEM_S_NO_ERROR;
// Strip off the root namespace prefix and generate the
// pseudo-name. We have no way of knowing if they entered this
// path correctly.
LPWSTR lpTemp3 = StripUnresolvedName (lpVal);
CDeleteMe <wchar_t> d2 (lpTemp3);
LPWSTR lpTemp2 = NULL;
lpTemp2 = GetKeyString(lpTemp3);
CDeleteMe <wchar_t> d (lpTemp2);
pQfr[iPos].pRefKey = new wchar_t [21];
if (pQfr[iPos].pRefKey)
swprintf(pQfr[iPos].pRefKey, L"%I64d", CRC64::GenerateHashValue(lpTemp2));
else
hr = WBEM_E_OUT_OF_MEMORY;
}
pQfr[iPos].pValue = new wchar_t[wcslen(lpVal)+1];
if (pQfr[iPos].pValue)
wcscpy(pQfr[iPos].pValue,lpVal);
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else
pQfr[iPos].pValue = NULL;
}
else
break;
}
else
{
if (lpVal)
{
pQfr[iPos].pValue = new wchar_t[wcslen(lpVal)+1];
if (pQfr[iPos].pValue)
wcscpy(pQfr[iPos].pValue,lpVal);
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else
pQfr[iPos].pValue = NULL;
pQfr[iPos].pRefKey = NULL;
}
iPos++;
}
}
}
else
{
if (lpPath)
{
hr = GetVariantFromArray(psaArray, i, iType, vTemp);
IUnknown *pTemp = V_UNKNOWN(&vTemp);
if (pTemp)
{
BYTE *pBuff = NULL;
DWORD dwLen;
_IWmiObject *pInt = NULL;
hr = pTemp->QueryInterface(IID__IWmiObject, (void **)&pInt);
if (SUCCEEDED(hr))
{
pInt->GetObjectMemory(NULL, 0, &dwLen);
pBuff = new BYTE [dwLen];
if (pBuff)
{
CDeleteMe <BYTE> d (pBuff);
DWORD dwLen1;
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
if (SUCCEEDED(hr))
{
hr = CSQLExecProcedure::InsertBlobData (pConn, dClassId, dObjectId,
dwPropertyID, NULL, i, 0);
wchar_t wSQL[1024];
swprintf(wSQL, L"select PropertyImageValue from ClassImages where ObjectId = %I64d and PropertyId = %ld"
L" and ArrayPos = %ld",
dObjectId, dwPropertyID, i);
hr = CSQLExecute::WriteImageValue(pCmd, wSQL, 1, pBuff, dwLen);
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
pInt->Release();
}
else
break;
}
}
}
}
if (SUCCEEDED(hr))
hr = CSQLExecProcedure::InsertBatch (pConn, dObjectId, 0, 0, pQfr, iPos);
// Finally clean up the upper array bounds
// (if this array used to be bigger...)
// ====================================
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(), L"delete from ClassData where ObjectId = %I64d and PropertyId = %ld and "
L" QfrPos = %ld and ArrayPos >= %ld", NULL, NULL, dObjectId, dwPropertyID, dwRefID, i);
}
delete pQfr;
}
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::Enumerate
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiDbSession::Enumerate(
/* [in] */ IWmiDbHandle __RPC_FAR *pScope,
/* [in] */ DWORD dwFlags,
/* [in] */ DWORD dwRequestedHandleType,
/* [out] */ IWmiDbIterator __RPC_FAR *__RPC_FAR *ppQueryResult)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!m_pController ||
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
return WBEM_E_SHUTTING_DOWN;
if (dwRequestedHandleType == WMIDB_HANDLE_TYPE_INVALID || !pScope)
return WBEM_E_INVALID_PARAMETER;
if (dwRequestedHandleType & ~WMIDB_HANDLE_TYPE_COOKIE
&~WMIDB_HANDLE_TYPE_VERSIONED &~WMIDB_HANDLE_TYPE_PROTECTED
&~WMIDB_HANDLE_TYPE_EXCLUSIVE &~ WMIDB_HANDLE_TYPE_WEAK_CACHE
&~WMIDB_HANDLE_TYPE_STRONG_CACHE &~ WMIDB_HANDLE_TYPE_NO_CACHE
&~WMIDB_HANDLE_TYPE_SUBSCOPED &~WMIDB_HANDLE_TYPE_CONTAINER
&~ WMIDB_HANDLE_TYPE_SCOPE)
return WBEM_E_INVALID_PARAMETER;
try
{
if (!((CWmiDbController *)m_pController)->m_bCacheInit)
{
hr = LoadSchemaCache();
if (SUCCEEDED(hr))
((CWmiDbController *)m_pController)->m_bCacheInit = TRUE;
else
return hr;
}
MappedProperties *pProps;
DWORD dwNumProps;
BOOL bHierarchy = FALSE;
SQL_ID dwNsId = 0, dClassId = 0;
_bstr_t sPath;
int iNumRows = 0;
IWbemClassObject *pTemp = NULL;
if (pScope)
{
dwNsId = ((CWmiDbHandle *)pScope)->m_dObjectId;
dClassId = ((CWmiDbHandle *)pScope)->m_dClassId;
// CVADAI: This is a container, not a scope: parent scopes not cached
// hr = VerifyObjectSecurity(dwNsId, 0, 0, 0, WBEM_ENABLE);
}
if (SUCCEEDED(hr))
{
DWORD dwRows;
IRowset *pRowset = NULL;
CSQLConnection *pConn = NULL;
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
if (SUCCEEDED(hr))
{
wchar_t sSQL [1024];
DWORD dwHandleType = ((CWmiDbHandle *)pScope)->m_dwHandleType;
if (dClassId == INSTANCESCLASSID)
{
SQL_ID dScopeId = ((CWmiDbHandle *)pScope)->m_dScopeId;
swprintf(sSQL, L"select ObjectId, ClassId, ObjectScopeId "
L" from ObjectMap where ClassId = %I64d"
L" and ObjectScopeId = %I64d",
dwNsId, dScopeId);
}
else if (dwHandleType & WMIDB_HANDLE_TYPE_CONTAINER)
{
DWORD dwContainerId = 0, dwContaineeId = 0;
swprintf(sSQL, L"select ObjectId, ClassId, ObjectScopeId from ObjectMap as o "
L" inner join ContainerObjs as c on c.ContaineeId = o.ObjectId "
L" and c.ContainerId = %I64d",
((CWmiDbHandle *)pScope)->m_dObjectId);
}
// Scope
else
{
swprintf(sSQL, L"select ObjectId, ClassId, ObjectScopeId "
L" from ObjectMap where ObjectScopeId = %I64d ",
dwNsId);
}
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(), sSQL, &pRowset, &dwRows);
if (SUCCEEDED(hr))
{
CWmiDbIterator *pNew = new CWmiDbIterator;
if (pNew)
{
*ppQueryResult = (IWmiDbIterator *)pNew;
pNew->m_pRowset = pRowset;
pNew->m_pConn = pConn; // Releasing the iterator will release this guy.
pNew->m_pSession = this;
pNew->m_pIMalloc = m_pIMalloc;
pNew->AddRef();
AddRef();
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else if (pRowset)
pRowset->Release();
}
}
}
}
catch (...)
{
ERRORTRACE((LOG_WBEMCORE, "Fatal error in CWmiDbSession::Enumerate"));
hr = WBEM_E_CRITICAL_ERROR;
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::ExecQuery
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiDbSession::ExecQuery(
/* [in] */ IWmiDbHandle __RPC_FAR *pScope,
/* [in] */ IWbemQuery __RPC_FAR *pQuery,
/* [in] */ DWORD dwFlags,
/* [in] */ DWORD dwHandleType,
/* [out] */ DWORD *pMessageFlags,
/* [out] */ IWmiDbIterator __RPC_FAR *__RPC_FAR *pQueryResult)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!m_pController ||
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
return WBEM_E_SHUTTING_DOWN;
if (dwHandleType == WMIDB_HANDLE_TYPE_INVALID || !pQuery || !pQueryResult || !pScope)
return WBEM_E_INVALID_PARAMETER;
if (dwFlags & ~WMIDB_FLAG_QUERY_DEEP &~WMIDB_FLAG_QUERY_SHALLOW & ~WBEM_FLAG_USE_SECURITY_DESCRIPTOR)
return WBEM_E_INVALID_PARAMETER;
if (dwHandleType & ~WMIDB_HANDLE_TYPE_COOKIE
&~WMIDB_HANDLE_TYPE_VERSIONED &~WMIDB_HANDLE_TYPE_PROTECTED
&~WMIDB_HANDLE_TYPE_EXCLUSIVE &~ WMIDB_HANDLE_TYPE_WEAK_CACHE
&~WMIDB_HANDLE_TYPE_STRONG_CACHE &~ WMIDB_HANDLE_TYPE_NO_CACHE
&~WMIDB_HANDLE_TYPE_SUBSCOPED &~ WMIDB_HANDLE_TYPE_SCOPE &~ WMIDB_HANDLE_TYPE_CONTAINER)
return WBEM_E_INVALID_PARAMETER;
if (pMessageFlags)
*pMessageFlags = WBEM_REQUIREMENTS_STOP_POSTFILTER;
try
{
if (!((CWmiDbController *)m_pController)->m_bCacheInit)
{
hr = LoadSchemaCache();
if (SUCCEEDED(hr))
((CWmiDbController *)m_pController)->m_bCacheInit = TRUE;
else
return hr;
}
// ExecQuery needs to call into the custom repository code
// if the scope is marked custom, and the query is not
// against instances of system classes.
// TO DO: We should allow cross-namespace
// queries at some point, such as "select * from __Namespace"
// Ignoring for now.
MappedProperties *pProps;
DWORD dwNumProps;
BOOL bHierarchy = FALSE;
SQL_ID dClassId = 0;
BOOL bDeleteQuery = FALSE;
BOOL bCountQuery = FALSE;
BOOL bDefaultIt = FALSE;
if (!pQuery)
{
hr = WBEM_E_INVALID_PARAMETER;
}
else
{
_bstr_t sSQL;
CSQLBuilder bldr(&((CWmiDbController *)m_pController)->SchemaCache);
SQL_ID dwNsId = 0;
_bstr_t sPath;
int iNumRows = 0;
IWbemClassObject *pTemp = NULL;
DWORD dwScopeType = ((CWmiDbHandle *)pScope)->m_dwHandleType ;
if (pScope && !(dwScopeType & WMIDB_HANDLE_TYPE_CONTAINER))
{
dwNsId = ((CWmiDbHandle *)pScope)->m_dObjectId;
hr=VerifyObjectSecurity (NULL, pScope, WBEM_ENABLE);
}
if (SUCCEEDED(hr))
{
SWbemAssocQueryInf *pNode = NULL;
hr = pQuery->GetAnalysis(WMIQ_ANALYSIS_ASSOC_QUERY,
0, (void **)&pNode);
if (FAILED(hr))
{
hr = bldr.FormatSQL(((CWmiDbHandle *)pScope)->m_dObjectId, ((CWmiDbHandle *)pScope)->m_dClassId,
((CWmiDbHandle *)pScope)->m_dScopeId, pQuery, sSQL, dwFlags,
((CWmiDbHandle *)pScope)->m_dwHandleType, &dClassId, &bHierarchy, TRUE, &bDeleteQuery,
&bDefaultIt);
// Special handling for non-meta-schema queries in
// the custom mapped namespace.
if (((CWmiDbHandle *)pScope)->m_bDefault)
bDefaultIt = TRUE;
if (!bDefaultIt)
{
SWQLNode *pTop = NULL;
pQuery->GetAnalysis(WMIQ_ANALYSIS_RESERVED, 0, (void **)&pTop);
if (pTop)
{
if (pTop->m_pLeft != NULL)
{
if (pTop->m_pLeft->m_dwNodeType == TYPE_SWQLNode_Delete)
bDeleteQuery = TRUE;
}
}
hr = CustomFormatSQL(pScope, pQuery, sSQL, &dClassId, &pProps, &dwNumProps, &bCountQuery);
}
if (hr == WBEM_E_PROVIDER_NOT_CAPABLE)
{
if (pMessageFlags)
{
*pMessageFlags = WBEM_REQUIREMENTS_START_POSTFILTER;
hr = WBEM_S_NO_ERROR;
}
}
// Make sure we have access to the target class.
// We won't check locks at this point, since that will
// be the iterator's job.
if (SUCCEEDED(hr))
{
hr=VerifyClassSecurity (NULL, dClassId, WBEM_ENABLE);
}
}
else
{
if (!((CWmiDbHandle *)pScope)->m_bDefault)
{
hr = WBEM_E_INVALID_QUERY;
}
else
{
bDefaultIt = TRUE;
SQL_ID dObjId = 0;
// Get dObjId.
IWbemPath *pPath = NULL;
hr = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
IID_IWbemPath, (LPVOID *) &pPath);
CReleaseMe r8 (pPath);
if (SUCCEEDED(hr))
{
pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, pNode->m_pszPath);
IWmiDbHandle *pTemp = NULL;
// WARNING: This fails if pScope is a container.
// We need to get the parent scope, or
// use the absolute path
// We aren't supporting this scenario
hr = GetObject(pScope, pPath, dwFlags, WMIDB_HANDLE_TYPE_COOKIE, &pTemp);
CReleaseMe r1 (pTemp);
if (SUCCEEDED(hr))
{
BOOL bIsClass = FALSE;
if (((CWmiDbHandle *)pTemp)->m_dClassId == 1)
bIsClass = TRUE;
SQL_ID dAssocClassId = 0, dResultClassId = 0;
dObjId = ((CWmiDbHandle *)pTemp)->m_dObjectId;
hr = bldr.FormatSQL(((CWmiDbHandle *)pScope)->m_dObjectId,
((CWmiDbHandle *)pScope)->m_dClassId,
((CWmiDbHandle *)pScope)->m_dScopeId,
dObjId,
pNode->m_pszResultClass,
pNode->m_pszAssocClass,
pNode->m_pszRole,
pNode->m_pszResultRole,
pNode->m_pszRequiredQualifier,
pNode->m_pszRequiredAssocQualifier,
pNode->m_uFeatureMask, sSQL,
dwFlags, ((CWmiDbHandle *)pScope)->m_dwHandleType,
&dAssocClassId, &dResultClassId, bIsClass);
if (SUCCEEDED(hr))
{
if (pMessageFlags)
{
if (bIsClass ||
pNode->m_pszRequiredQualifier ||
pNode->m_pszRequiredAssocQualifier)
{
*pMessageFlags = WBEM_REQUIREMENTS_START_POSTFILTER;
hr = WBEM_S_NO_ERROR;
}
}
// Make sure we have read access on all these classes.
hr=VerifyClassSecurity (NULL, dObjId, WBEM_ENABLE);
if (SUCCEEDED(hr) && dAssocClassId)
{
hr=VerifyClassSecurity (NULL, dAssocClassId, WBEM_ENABLE);
}
if (SUCCEEDED(hr) && dResultClassId)
{
hr=VerifyClassSecurity(NULL, dResultClassId, WBEM_ENABLE);
}
}
}
}
}
}
}
if (SUCCEEDED(hr))
{
DWORD dwRows;
IRowset *pRowset = NULL;
CSQLConnection *pConn = NULL;
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
if (SUCCEEDED(hr))
{
if (bHierarchy && SUCCEEDED(hr))
hr = CSQLExecProcedure::GetHierarchy(pConn, dClassId);
if (SUCCEEDED(hr) && dwFlags & WMIDB_FLAG_QUERY_DEEP)
hr = CSQLExecProcedure::EnumerateSubScopes(pConn, dwNsId);
if (!bDefaultIt)
{
IWbemClassObject *pObj = NULL;
hr = GetClassObject(pConn, dClassId, &pObj);
if (SUCCEEDED(hr))
{
hr = GetObjectCache()->PutObject(dClassId, 1,
((CWmiDbHandle *)pScope)->m_dObjectId, L"", 1, pObj);
pObj->Release();
}
}
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(), sSQL, &pRowset, &dwRows);
if (SUCCEEDED(hr))
{
if (bDefaultIt)
{
CWmiDbIterator *pNew = new CWmiDbIterator;
if (pNew)
{
pNew->m_pRowset = pRowset;
pNew->m_pConn = pConn; // Releasing the iterator will release this guy.
pNew->m_pSession = this;
pNew->m_pIMalloc = m_pIMalloc;
pNew->AddRef();
AddRef();
// If this is a delete query, we need to
// stuff the results back into the DeleteObject
// call, to keep ESS happy.
if (bDeleteQuery)
{
hr = DeleteRows(pScope, pNew, IID_IWmiDbHandle);
pNew->Release();
*pQueryResult = NULL;
}
// select query. Give them the iterator
else if (pQueryResult)
{
*pQueryResult = (IWmiDbIterator *)pNew;
}
}
else
{
pRowset->Release();
hr = WBEM_E_OUT_OF_MEMORY;
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
}
}
else
{
// We need to create a custom iterator
CWmiCustomDbIterator *pNew = new CWmiCustomDbIterator;
if (pNew)
{
pNew->m_pRowset = pRowset;
pNew->m_pConn = pConn; // Releasing the iterator will release this guy.
pNew->m_pSession = this;
pNew->m_pIMalloc = m_pIMalloc;
pNew->m_pPropMapping = pProps;
pNew->m_dwNumProps = dwNumProps;
pNew->m_dwScopeId = dwNsId;
pNew->m_pScope = pScope;
pNew->m_dClassId = dClassId;
pNew->m_bCount = bCountQuery;
pNew->AddRef();
AddRef();
if (bDeleteQuery)
{
hr = DeleteRows(pScope, pNew, IID_IWbemClassObject);
pNew->Release();
*pQueryResult = NULL;
}
// select query. Give them the iterator
else if (pQueryResult)
{
*pQueryResult = (IWmiDbIterator *)pNew;
}
}
}
}
else if (pRowset)
pRowset->Release();
}
}
}
}
}
catch (...)
{
ERRORTRACE((LOG_WBEMCORE, "Fatal error in CWmiDbSession::ExecQuery"));
hr = WBEM_E_CRITICAL_ERROR;
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::Delete
//
//***************************************************************************
HRESULT CWmiDbSession::Delete(IWmiDbHandle *pHandle, CSQLConnection *pConn)
{
HRESULT hr = WBEM_S_NO_ERROR;
IRowset *pIRowset = NULL;
DWORD dwNumRows = 0;
CWmiDbHandle *pTmp = (CWmiDbHandle *)pHandle;
bool bLocalTrans = false;
if (!m_pController ||
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
return WBEM_E_SHUTTING_DOWN;
SQL_ID dID = pTmp->m_dObjectId;
SQL_ID dClassID = pTmp->m_dClassId;
hr = VerifyObjectLock(dID, pTmp->m_dwHandleType, pTmp->m_dwVersion);
if (FAILED(hr) && IsDistributed())
{
if (LockExists(dID))
hr = WBEM_S_NO_ERROR;
}
if (SUCCEEDED(hr))
{
if (!pConn)
{
bLocalTrans = true;
hr = GetSQLCache()->GetConnection(&pConn, TRUE, IsDistributed());
if (FAILED(hr))
return hr;
}
if (SUCCEEDED(hr))
{
SQLIDs ObjIds, ClassIds, ScopeIds;
// Was this a class or an instance?
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(), L"exec pDelete %I64d", &pIRowset, &dwNumRows, dID);
CReleaseMe r (pIRowset);
VARIANT vTemp;
CClearMe c (&vTemp);
HROW *pRow = NULL;
SQL_ID dObjectId = 0, dClassId = 0, dScopeId = 0;
if (SUCCEEDED(hr) && pIRowset)
{
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && vTemp.vt != VT_EMPTY && vTemp.vt != VT_NULL)
{
// Make sure we had permission to do this.
// We should probably somehow 'put back'
// whatever we removed from the cache.
// =======================================
dObjectId = _wtoi64(vTemp.bstrVal);
hr = CSQLExecute::GetColumnValue(pIRowset, 2, m_pIMalloc, &pRow, vTemp);
dClassId = _wtoi64(vTemp.bstrVal);
hr = CSQLExecute::GetColumnValue(pIRowset, 3, m_pIMalloc, &pRow, vTemp);
dScopeId = _wtoi64(vTemp.bstrVal);
// Just add these values to an array
// and remove them if everything else succeeds.
// ============================================
ObjIds.push_back(dObjectId);
ClassIds.push_back(dClassId);
ScopeIds.push_back(dScopeId);
if (pRow)
pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
}
}
// Verify that we had security to do this...
if (SUCCEEDED(hr))
{
for (int i = 0; i < ObjIds.size(); i++)
{
dClassId = ClassIds.at(i);
dScopeId = ScopeIds.at(i);
if (dClassId && dScopeId)
{
hr = VerifyObjectSecurity(pConn, ObjIds.at(i), dClassId, dScopeId, 0,
GetSchemaCache()->GetWriteToken(ObjIds.at(i), dClassId));
if (FAILED(hr))
break;
}
}
}
if (bLocalTrans)
{
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
}
if (SUCCEEDED(hr))
{
for (int i = 0; i < ObjIds.size(); i++)
{
// We have no way of knowing by ID if this is a class or instance.
GetSchemaCache()->DeleteClass(ObjIds.at(i));
CleanCache(ObjIds.at(i));
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLConnCache::FinalRollback
//
//***************************************************************************
HRESULT CSQLConnCache::FinalRollback(CSQLConnection *pConn)
{
HRESULT hr = WBEM_S_NO_ERROR;
// Rollback this transaction and set Thread ID to zero
COLEDBConnection *pConn2 = (COLEDBConnection *)pConn;
ITransaction *pTrans = pConn2->m_pTrans;
if (pTrans)
{
hr = pTrans->Abort(NULL, FALSE, FALSE);
pTrans->Release();
}
pConn2->m_pTrans = NULL;
pConn2->m_bInUse = false;
pConn2->m_dwThreadId = 0;
pConn2->m_tCreateTime = time(0); // We don't want to delete it immediately.
return hr;
}
//***************************************************************************
//
// CSQLConnCache::FinalCommit
//
//***************************************************************************
HRESULT CSQLConnCache::FinalCommit(CSQLConnection *pConn)
{
HRESULT hr = WBEM_S_NO_ERROR;
// Commit this transaction and erase the ThreadID
// from this connection.
COLEDBConnection *pConn2 = (COLEDBConnection *)pConn;
ITransaction *pTrans = pConn2->m_pTrans;
if (pTrans)
{
hr = pTrans->Commit(FALSE, XACTTC_SYNC, 0);
pTrans->Release();
}
pConn2->m_bInUse = false;
pConn2->m_dwThreadId = 0;
pConn2->m_tCreateTime = time(0); // We don't want to delete it immediately.
pConn2->m_pTrans = NULL;
return hr;
}
//***************************************************************************
//
// CSQLConnCache::ReleaseConnection
//
//***************************************************************************
HRESULT CSQLConnCache::ReleaseConnection(CSQLConnection *_pConn, HRESULT retcode,
BOOL bDistributed)
{
HRESULT hr = WBEM_S_NO_ERROR;
DWORD dwNumFreed = 0;
CRepdrvrCritSec r (&m_cs);
for (int i = m_Conns.size() -1; i >=0; i--)
{
CSQLConnection *pConn = m_Conns.at(i);
if (pConn)
{
COLEDBConnection *pConn2 = (COLEDBConnection *)pConn;
if (_pConn == pConn)
{
if (FAILED(retcode))
{
if (!bDistributed)
{
hr = FinalRollback(pConn);
if (retcode == WBEM_E_INVALID_QUERY)
{
delete pConn;
pConn2 = NULL;
m_Conns.erase(&m_Conns.at(i));
DEBUGTRACE((LOG_WBEMCORE, "THREAD %ld deleted ESE connection %X. Number of connections = %ld\n",
GetCurrentThreadId(), pConn, m_Conns.size()));
}
}
}
else
{
if (!bDistributed)
hr = FinalCommit(pConn);
}
if (pConn2)
pConn2->m_bInUse = false;
dwNumFreed++;
break;
}
}
}
// Notify waiting threads that there is
// an open connection.
// =====================================
for (int i = 0; i < m_WaitQueue.size(); i++)
{
if (i >= dwNumFreed)
break;
HANDLE hTemp = m_WaitQueue.at(i);
SetEvent(hTemp);
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld released a connection...\n", GetCurrentThreadId()));
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::LoadSchemaCache
//
//***************************************************************************
HRESULT CWmiDbSession::LoadSchemaCache ()
{
HRESULT hr = WBEM_S_NO_ERROR;
// This needs to load the cache with all class, property,
// and namespace data. We are going to call three straight
// select queries and grab the columns.
// ==========================================================
IRowset *pIRowset = NULL;
DWORD dwNumRows;
_bstr_t sSQL;
CSQLConnection *pConn = NULL;
hr = GetSQLCache()->GetConnection(&pConn, FALSE, FALSE);
if (FAILED(hr))
return hr;
// FIXME: We need to sort out how to do this correctly,
// and NOT compromise speed.
GetSchemaCache()->SetMaxSize(0xFFFFFFFF);
// Enumerate namespaces and scopes.
// ================================
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(), L"sp_EnumerateNamespaces", &pIRowset, &dwNumRows);
if (SUCCEEDED(hr))
{
// Get the results and load the cache.
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
SQL_ID dObjectId = _wtoi64(vTemp.bstrVal);
SQL_ID dParentId = 0, dClassId = 0;
_bstr_t sObjectPath, sObjectKey;
VariantClear(&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 2, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
sObjectPath = vTemp.bstrVal;
hr = CSQLExecute::GetColumnValue(pIRowset, 3, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
sObjectKey = vTemp.bstrVal;
if (SUCCEEDED(hr))
{
hr = CSQLExecute::GetColumnValue(pIRowset, 4, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dParentId = _wtoi64(vTemp.bstrVal);
hr = CSQLExecute::GetColumnValue(pIRowset, 5, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dClassId = _wtoi64(vTemp.bstrVal);
hr = GetSchemaCache()->AddNamespace(sObjectPath, sObjectKey, dObjectId, dParentId, dClassId);
}
hr = pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
}
pIRowset->Release();
pIRowset = NULL;
}
if (FAILED(hr))
return hr;
if (FAILED(hr = LoadClassInfo(pConn, L"", 0)))
return hr;
DWORD dwSecurity = 0;
GetSchemaCache()->GetPropertyID(L"__SECURITY_DESCRIPTOR", 1,
0, REPDRVR_IGNORE_CIMTYPE, dwSecurity);
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"select ObjectId from ClassImages where PropertyId = %ld", &pIRowset, &dwNumRows, dwSecurity);
if (SUCCEEDED(hr))
{
// Get the results and load the cache.
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
SQL_ID dObjectId = _wtoi64(vTemp.bstrVal);
pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
((CWmiDbController *)m_pController)->AddSecurityDescriptor(dObjectId);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
}
pIRowset->Release();
pIRowset = NULL;
}
GetSQLCache()->ReleaseConnection(pConn, hr, FALSE);
return hr;
}
//***************************************************************************
//
// CWmiDbSession::LoadClassInfo
//
//***************************************************************************
HRESULT CWmiDbSession::LoadClassInfo (CSQLConnection *pConn, LPCWSTR lpDynasty, SQL_ID dScopeId, BOOL bDeep)
{
HRESULT hr = WBEM_S_NO_ERROR;
IRowset *pIRowset = NULL;
DWORD dwNumRows;
// FIXME: We need to make this selective, but reading
// this data is so slow!!
// The cache relies on the numeric value of scope and super class objects.
// =======================================================================
if (((CWmiDbController *)m_pController)->m_bCacheInit)
return hr;
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"select c.ClassId, c.ClassName, c.SuperClassId, o.ObjectScopeId, o.ObjectPath,o.ObjectFlags from ClassMap as c "
L" inner join ObjectMap as o on o.ObjectId = c.ClassId "
L" order by c.ClassId ", &pIRowset, &dwNumRows);
if (SUCCEEDED(hr))
{
// Get the results and load the cache.
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
SQL_ID dObjectId = _wtoi64(vTemp.bstrVal);
_bstr_t sClassName, sPath;
SQL_ID dParentId = 0, dScopeId = 0;
DWORD dwFlags = 0;
VariantClear(&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 2, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
sClassName = vTemp.bstrVal;
hr = CSQLExecute::GetColumnValue(pIRowset, 3, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
{
if (vTemp.vt != VT_EMPTY && vTemp.vt != VT_NULL)
dParentId = _wtoi64(vTemp.bstrVal);
else
dParentId = 1;
}
hr = CSQLExecute::GetColumnValue(pIRowset, 4, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
{
if (vTemp.vt != VT_EMPTY && vTemp.vt != VT_NULL)
dScopeId = _wtoi64(vTemp.bstrVal);
else
dScopeId = 0;
}
hr = CSQLExecute::GetColumnValue(pIRowset, 5, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
sPath = vTemp.bstrVal;
hr = CSQLExecute::GetColumnValue(pIRowset, 6, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dwFlags = ((vTemp.vt == VT_EMPTY || vTemp.vt == VT_NULL) ? 0 : vTemp.lVal);
else
dwFlags = 0;
hr = GetSchemaCache()->AddClassInfo(dObjectId, sClassName, dParentId, 0, dScopeId, sPath, dwFlags);
pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
if (FAILED(hr))
break;
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
}
pIRowset->Release();
pIRowset = NULL;
}
if (FAILED(hr))
return hr;
// Enumerate properties.
// ======================
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"select p.PropertyId, p.PropertyName, p.ClassId, p.StorageTypeId, p.CIMTypeId, p.Flags, 0, "
L" c.PropertyId "
L"from PropertyMap as p left outer join ClassKeys as c on c.ClassId = p.ClassId and c.PropertyId = p.PropertyId "
L" order by p.PropertyId ",
&pIRowset, &dwNumRows);
if (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
// Get the results and load the cache.
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
DWORD dwPropertyID=0, dwStorageType=0, dwCIMType=0, dwFlags=0, dwFlavor=0;
_bstr_t sName, sDefault;
SQL_ID dClassId = 0, dRefClassID = 0;
DWORD dwRefPropID = 0;
dwPropertyID = vTemp.lVal;
VariantClear(&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 2, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
sName = vTemp.bstrVal;
hr = CSQLExecute::GetColumnValue(pIRowset, 3, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dClassId = _wtoi64(vTemp.bstrVal); // We want the applied class ID for qualifiers.
hr = CSQLExecute::GetColumnValue(pIRowset, 4, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dwStorageType = vTemp.lVal;
hr = CSQLExecute::GetColumnValue(pIRowset, 5, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dwCIMType = (vTemp.vt == VT_I4 ? vTemp.lVal : 0);
else
dwCIMType = 0;
hr = CSQLExecute::GetColumnValue(pIRowset, 6, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dwFlags = (vTemp.vt == VT_I4 ? vTemp.lVal : 0);
else
dwFlags = 0;
if (dwCIMType == CIM_REFERENCE || dwCIMType == CIM_OBJECT)
{
hr = CSQLExecute::GetColumnValue(pIRowset, 7, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
dRefClassID = _wtoi64(vTemp.bstrVal);
}
hr = GetSchemaCache()->AddPropertyInfo (dwPropertyID, sName, dClassId, dwStorageType, dwCIMType, dwFlags,
dRefClassID, sDefault, dwRefPropID, dwFlavor);
hr = CSQLExecute::GetColumnValue(pIRowset, 8, m_pIMalloc, &pRow, vTemp);
if (SUCCEEDED(hr) && vTemp.vt != VT_NULL)
GetSchemaCache()->SetIsKey(dClassId, dwPropertyID);
pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
if (FAILED(hr))
break;
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp);
}
pIRowset->Release();
pIRowset = NULL;
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::LoadClassInfo
//
//***************************************************************************
HRESULT CWmiDbSession::LoadClassInfo (CSQLConnection *_pConn, SQL_ID dClassId, BOOL bDeep)
{
HRESULT hr = WBEM_S_NO_ERROR;
// Not implemented (yet).
return hr;
}
//***************************************************************************
//
// CWmiDbSession::GetClassObject
//
//***************************************************************************
HRESULT CWmiDbSession::GetClassObject (CSQLConnection *pConn, SQL_ID dClassId, IWbemClassObject **ppObj)
{
HRESULT hr = WBEM_S_NO_ERROR;
_IWmiObject *pNew = NULL;
SQL_ID dParentId = 0;
SQL_ID dSuperClassId = 0;
DWORD dwBufferLen = 0;
BYTE *pBuffer = NULL;
// All we need to do is read the blob from the database.
// This should be cached where space allows.
BOOL bNeedToRelease = FALSE;
if (!pConn)
{
hr = GetSQLCache()->GetConnection(&pConn, 0, IsDistributed());
bNeedToRelease = TRUE;
if (FAILED(hr))
return hr;
}
hr = CSQLExecProcedure::GetClassInfo(pConn, dClassId, dSuperClassId, &pBuffer, dwBufferLen);
if (SUCCEEDED(hr) && pBuffer)
{
if (dSuperClassId != 0 && dSuperClassId != 1)
{
hr = GetObjectCache()->GetObject(dSuperClassId, ppObj);
if (FAILED(hr))
hr = GetClassObject(pConn, dSuperClassId, ppObj);
if (SUCCEEDED(hr))
{
// Merge the class part.
_IWmiObject *pObj = (_IWmiObject *)*ppObj;
hr = pObj->Merge (WMIOBJECT_MERGE_FLAG_CLASS, dwBufferLen, pBuffer, &pNew);
pObj->Release();
if (SUCCEEDED(hr))
*ppObj = pNew;
}
}
else
{
_IWmiObject *pObj = NULL;
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
IID__IWmiObject, (void **)&pObj);
if (SUCCEEDED(hr))
{
hr = pObj->Merge(WMIOBJECT_MERGE_FLAG_CLASS, dwBufferLen, pBuffer, &pNew);
pObj->Release();
if (SUCCEEDED(hr))
*ppObj = pNew;
}
}
}
else
hr = WBEM_E_NOT_FOUND;
if (bNeedToRelease && pConn)
{
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
}
return hr;
}
//***************************************************************************
//
// CWmiDbSession::GetObjectData
//
//***************************************************************************
HRESULT CWmiDbSession::GetObjectData (CSQLConnection *pConn, SQL_ID dObjectId, SQL_ID dClassId, SQL_ID dScopeId,
DWORD dwHandleType, DWORD &dwVersion, IWbemClassObject **ppObj, BOOL bWaste,
LPWSTR lpInKey, BOOL bGetSD )
{
_WMILockit _Lk(GetCS());
HRESULT hr = WBEM_S_NO_ERROR;
SQL_ID dParentId;
_bstr_t sClassPath = L"", sClassName = L"";
DWORD dwGenus = 1;
DWORD dwRows;
IRowset *pIRowset = NULL;
DWORD dwFlags;
bool bUsedCache = false;
DWORD dwType = 0, dwVer = 0;
// Validate version if this is a versioned handle.
// ================================================-
hr = VerifyObjectLock(dObjectId, dwHandleType, dwVersion);
if (FAILED(hr) && IsDistributed())
{
if (LockExists(dObjectId))
hr = WBEM_S_NO_ERROR;
}
if (SUCCEEDED(hr))
{
// Check the object cache to see if this
// IWbemClassObject is already loaded.
// =====================================
if (dClassId == INSTANCESCLASSID)
hr = WBEM_E_NOT_FOUND;
else
{
hr = GetObjectCache()->GetObject(dObjectId, ppObj);
}
if (FAILED(hr))
{
hr = WBEM_S_NO_ERROR;
IDBInitialize *pDBInit = NULL;
// Otherwise, we need to hit the database.
// =======================================
HROW *pRow = NULL;
BOOL bNeedToRelease = FALSE;
IDBCreateCommand *pCommand = NULL;
if (!pConn)
{
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
bNeedToRelease = TRUE;
if (FAILED(hr))
return hr;
}
pCommand = ((COLEDBConnection *)pConn)->GetCommand();
if (SUCCEEDED(hr))
{
if (dClassId == 1)
{
dwGenus = 1;
dClassId = dObjectId;
}
else
dwGenus = 2;
SQL_ID dTemp = 0;
hr = GetSchemaCache()->GetClassInfo(dClassId, sClassPath, dParentId, dTemp, dwFlags);
// We now have an object path and class ID.
// Now we have to instantiate a new IWbemClassObject,
// populate all the system properties
// ==================================================
IWbemClassObject *pClass = NULL;
IWbemClassObject *pTemp = NULL;
hr = GetObjectCache()->GetObject(dClassId, &pClass);
if (FAILED(hr))
hr = GetClassObject (pConn, dClassId, &pClass);
else
bUsedCache = true;
if (SUCCEEDED(hr))
{
if (dwGenus == 2)
{
if (pClass)
{
pClass->SpawnInstance(0, &pTemp);
}
}
else
{
pTemp = pClass;
}
// Special case if this is an __Instances container,
// We need to instantiate an instance of __Instances,
// and plug the class name into the ClassName property.
// ===================================================
if (dClassId == INSTANCESCLASSID)
{
_bstr_t sPath;
_bstr_t sName;
SQL_ID dTemp1, dTemp2;
DWORD dwFlags;
hr = GetSchemaCache()->GetClassInfo (dObjectId, sPath, dTemp1, dTemp2, dwFlags, &sName);
if (SUCCEEDED(hr))
{
VARIANT vTemp;
VariantInit(&vTemp);
vTemp.bstrVal = SysAllocString(sName);
vTemp.vt = VT_BSTR;
pTemp->Put(L"ClassName", 0, &vTemp, CIM_STRING);
VariantClear(&vTemp);
*ppObj = pTemp;
}
}
else
{
if (dwGenus == 2)
{
// Now we are ready to get the real data.
// Basically, we have to select * from ClassData, and
// let CSQLExecute correctly interpret the data therein.
// ====================================================
bool bBigText = false;
HROW *pRow = NULL;
Properties props;
hr = CSQLExecute::ExecuteQuery(pCommand, L"sp_GetInstanceData %I64d", &pIRowset, &dwRows, dObjectId);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
if (!dwRows || dwRows == 0xffffffff)
dwRows = 20;
hr = CSQLExecuteRepdrvr::GetNextResultRows(dwRows, pIRowset, m_pIMalloc, pTemp,
&((CWmiDbController *)m_pController)->SchemaCache, this, props, &bBigText, false);
}
if (pIRowset)
pIRowset->Release();
//if (bBigText || GetSchemaCache()->HasImageProp(dClassId))
{
hr = CSQLExecute::ExecuteQuery(pCommand, L"sp_GetInstanceImageData %I64d", &pIRowset, &dwRows, dObjectId);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
if (!dwRows || dwRows == 0xffffffff)
dwRows = 1;
hr = CSQLExecuteRepdrvr::GetNextResultRows(dwRows, pIRowset, m_pIMalloc, pTemp,
&((CWmiDbController *)m_pController)->SchemaCache, this, props, NULL, true);
}
pIRowset->Release();
}
}
*ppObj = pTemp;
hr = WBEM_S_NO_ERROR;
// Always cache the class object.
if (!bUsedCache && SUCCEEDED(hr) && !((dwHandleType & 0xF00) == WMIDB_HANDLE_TYPE_NO_CACHE))
GetObjectCache()->PutObject(dClassId, 1, dScopeId, sClassPath, 1, pClass);
}
if (pTemp)
{
hr = GetSchemaCache()->DecorateWbemObj(m_sMachineName, m_sNamespacePath,
dScopeId, pTemp, dClassId);
}
// If all that worked, try and cache this object.
// ==============================================
if (SUCCEEDED(hr) && ppObj && (dwHandleType & 0xF00) && dClassId != INSTANCESCLASSID)
{
// This is allowed to fail, since its *just* a cache.
if ((dwHandleType & 0xF00) != WMIDB_HANDLE_TYPE_NO_CACHE)
{
bool bCacheType = ((dwHandleType & 0xF00) == WMIDB_HANDLE_TYPE_STRONG_CACHE) ? 1 : 0;
LPWSTR lpPath = GetPropertyVal(L"__RelPath", *ppObj);
if (lpPath)
GetObjectCache()->PutObject(dObjectId, dClassId, dScopeId, lpPath, bCacheType, *ppObj);
delete lpPath;
}
}
if (dwGenus == 2 && pClass)
pClass->Release();
}
if (bNeedToRelease)
{
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
}
}
}
else
{
// Make sure the decoration is up-to-date.
hr = GetSchemaCache()->DecorateWbemObj(m_sMachineName, m_sNamespacePath,
dScopeId, *ppObj, dClassId);
}
}
// Populate the security descriptor, if requested
if (SUCCEEDED(hr) && bGetSD)
{
BOOL bNeedToRelease = FALSE;
if (!pConn)
{
hr = GetSQLCache()->GetConnection(&pConn, 0, FALSE);
bNeedToRelease = TRUE;
if (FAILED(hr))
{
(*ppObj)->Release();
*ppObj = NULL;
return hr;
}
}
PNTSECURITY_DESCRIPTOR pSD = NULL;
DWORD dwLen = 0;
if (SUCCEEDED(CSQLExecProcedure::GetSecurityDescriptor(pConn, dObjectId, &pSD, dwLen, 0)))
{
((_IWmiObject *)*ppObj)->WriteProp(L"__SECURITY_DESCRIPTOR", 0, dwLen, dwLen, CIM_UINT8|CIM_FLAG_ARRAY, pSD);
delete pSD;
}
if (bNeedToRelease && pConn)
{
GetSQLCache()->ReleaseConnection(pConn, hr, FALSE);
}
}
return hr;
}
//***************************************************************************
//
// CSQLConnCache::Shutdown
//
//***************************************************************************
HRESULT CSQLConnCache::Shutdown()
{
return WBEM_S_NO_ERROR;
}
LPSTR EscapeChar (LPSTR lpText, char p = '%')
{
int iPos = 0;
int iLen = strlen(lpText);
char *pszTemp = NULL;
if (iLen)
{
pszTemp = new char [iLen+20];
if (pszTemp)
{
for (int i = 0; i < iLen; i++)
{
char t = lpText[i];
if (t == p)
{
pszTemp[iPos] = t;
iPos++;
}
pszTemp[iPos] = t;
iPos++;
}
pszTemp[iPos] = '\0';
}
}
return pszTemp;
}
//***************************************************************************
//
// InitializeClass
//
//***************************************************************************
HRESULT InitializeClass (CSQLConnection *pConn, LPCWSTR lpClassName, IWbemClassObject **ppObj)
{
HRESULT hr = 0;
_IWmiObject *pObj = NULL;
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
IID__IWmiObject, (void **)&pObj);
if (SUCCEEDED(hr))
{
VARIANT vTemp;
VariantInit(&vTemp);
vTemp.bstrVal = SysAllocString(lpClassName);
vTemp.vt = VT_BSTR;
pObj->Put(L"__Class", 0, &vTemp, CIM_STRING);
VariantClear(&vTemp);
}
*ppObj = (IWbemClassObject *)pObj;
return hr;
}
//***************************************************************************
//
// AddPropertyToClass
//
//***************************************************************************
HRESULT AddPropertyToClass (IWbemClassObject *pObj, LPCWSTR lpPropName,
CIMTYPE ct, BOOL bIsKey=FALSE, LPCWSTR lpCIMType = NULL)
{
HRESULT hr = 0;
VARIANT vTemp;
VariantInit(&vTemp);
pObj->Put(lpPropName, 0, NULL, ct);
IWbemQualifierSet *pQS = NULL;
if (bIsKey)
{
hr = pObj->GetPropertyQualifierSet(lpPropName, &pQS);
if (SUCCEEDED(hr))
{
vTemp.boolVal = 1;
vTemp.vt = VT_BOOL;
pQS->Put(L"key", &vTemp, 0);
pQS->Release();
VariantClear(&vTemp);
}
}
if (lpCIMType)
{
hr = pObj->GetQualifierSet(&pQS);
if (SUCCEEDED(hr))
{
vTemp.bstrVal = SysAllocString(lpCIMType);
vTemp.vt = VT_BSTR;
pQS->Put(L"CIMTYPE", &vTemp, 0);
pQS->Release();
VariantClear(&vTemp);
}
}
return hr;
}
//***************************************************************************
//
// Startup
//
//***************************************************************************
HRESULT Startup(HRESULT hrDB, CSQLConnection *pConn, LPCWSTR lpDatabaseName)
{
HRESULT hr = WBEM_S_NO_ERROR;
wchar_t SysPath[1024];
GetSystemDirectory(SysPath, 1023);
if (!wcslen(SysPath))
return WBEM_E_FAILED;
wcscat(SysPath, L"\\wbem\\repository\\");
_bstr_t sFile = SysPath;
sFile += lpDatabaseName;
sFile += L".tmp";
BOOL bCreate = FALSE;
if (FAILED(hrDB))
{
// Load and parse the file.
// Execute each query to each "go"
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"use master");
if (SUCCEEDED(hr))
{
ERRORTRACE((LOG_WBEMCORE, "SQL Database Creation...\n"));
printf ("Creating database %S...\n", lpDatabaseName);
// Just create on the default device with the default settings.
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L" CREATE DATABASE %s", NULL, NULL, lpDatabaseName);
if (SUCCEEDED(hr))
{
_bstr_t sFile = SysPath;
sFile += lpDatabaseName;
sFile += L".tmp";
FILE *p = fopen(sFile, "at");
if (p)
fclose(p);
bCreate = TRUE;
}
}
}
else
{
IRowset *pRowset = NULL;
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L" select Version from %s..DBVersion ", &pRowset, NULL, lpDatabaseName);
if (SUCCEEDED(hr) && pRowset)
{
VARIANT vTemp;
CClearMe c (&vTemp);
HROW *pRow = NULL;
IMalloc *pMalloc =NULL;
CoGetMalloc(MEMCTX_TASK, &pMalloc);
hr = CSQLExecute::GetColumnValue(pRowset, 1, pMalloc, &pRow, vTemp);
pMalloc->Release();
if (SUCCEEDED(hr) && vTemp.lVal != CURRENT_DB_VERSION)
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"use master");
ERRORTRACE((LOG_WBEMCORE, "Version mismatch detected. Dropping database: %S\n", (const wchar_t *)lpDatabaseName));
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"drop database %s",
NULL, NULL, lpDatabaseName);
hr = WBEM_E_DATABASE_VER_MISMATCH;
}
else
hr = WBEM_S_NO_ERROR;
pRowset->Release();
}
else
hr = WBEM_S_NO_ERROR;
}
if (SUCCEEDED(hr))
{
FILE *pTemp = fopen(sFile, "rt");
if (pTemp || bCreate)
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"exec sp_dboption %s, 'trunc', true", NULL, NULL, lpDatabaseName);
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"use master");
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L" IF NOT EXISTS (select * from systypes where name = 'WMISQL_ID') "
L" BEGIN "
L" exec sp_addtype WMISQL_ID, 'numeric(20,0)', 'NULL' "
L" END ");
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"use tempdb");
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L" IF NOT EXISTS (select * from systypes where name = 'WMISQL_ID') "
L" BEGIN "
L" exec sp_addtype WMISQL_ID, 'numeric(20,0)', 'NULL' "
L" END ");
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"use %s", NULL, NULL, lpDatabaseName);
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L" IF NOT EXISTS (select * from systypes where name = 'WMISQL_ID') "
L" BEGIN "
L" exec sp_addtype WMISQL_ID, 'numeric(20,0)', 'NULL' "
L" END ");
}
}
}
}
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"begin transaction ");
// Run the db scripts.
GetSystemDirectory(SysPath, 1023);
_bstr_t sPath = SysPath + _bstr_t(L"\\wbem\\createdb.sql");
FILE *fp = fopen(sPath, "rt");
if (fp)
{
char LineBuffer[2048];
_bstr_t sCmd;
// Read each line.
// ===============
DWORD dwReturnCode = NO_ERROR;
DWORD dwLine = 0;
while (fgets(LineBuffer, 1024, fp)) {
LineBuffer[strlen(LineBuffer)-1] = 0;
dwLine++;
if (memcmp(LineBuffer, "go", 2) == 0 || memcmp(LineBuffer, "GO", 2) == 0)
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),sCmd);
if (FAILED(hr))
break;
sCmd = L"";
}
else
{
int iRet = memcmp(LineBuffer, "/*", 2);
if (iRet)
{
LPSTR lpStr = EscapeChar(LineBuffer, '%');
sCmd += (const char *)lpStr;
sCmd += L"\r\n";
delete lpStr;
}
}
}
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"update %s..DBVersion set Version = %ld", NULL, NULL, lpDatabaseName, CURRENT_DB_VERSION);
fclose(fp);
// Initialize meta_class with new properties
IWbemClassObject *pTest = NULL;
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
IID_IWbemClassObject, (void **)&pTest);
if (SUCCEEDED(hr))
{
CReleaseMe r (pTest);
BSTR strName;
CIMTYPE cimtype;
hr = pTest->BeginEnumeration(0);
while (pTest->Next(0, &strName, NULL, &cimtype, NULL) == S_OK)
{
DWORD dwStorageType = 0;
CFreeMe f1 (strName);
DWORD dwFlags = REPDRVR_FLAG_SYSTEM;
bool bArray = false;
CIMTYPE ct = cimtype & 0xFFF;
if (cimtype & CIM_FLAG_ARRAY)
{
bArray = true;
dwFlags |= REPDRVR_FLAG_ARRAY;
}
if (_wcsicmp(strName, L"__Path") &&
_wcsicmp(strName, L"__RelPath") &&
_wcsicmp(strName, L"__Class") &&
_wcsicmp(strName, L"__SuperClass") &&
_wcsicmp(strName, L"__Dynasty") &&
_wcsicmp(strName, L"__Derivation") &&
_wcsicmp(strName, L"__Version") &&
_wcsicmp(strName, L"__Genus") &&
_wcsicmp(strName, L"__Property_Count") &&
_wcsicmp(strName, L"__Server") &&
_wcsicmp(strName, L"__Namespace"))
{
dwStorageType = GetStorageType(ct, bArray);
DWORD dwProp = 0;
hr = CSQLExecProcedure::InsertClassData (pConn,
pTest, NULL, 0, 1, strName, ct, dwStorageType, L"", 0, 0, dwFlags, 0, 0, dwProp, 1);
if (FAILED(hr))
goto Exit;
}
}
}
// Create the initial objects...
// __Namespace
// __Container_Association
// __Instances
IWbemClassObject *pObj = NULL, *pDerived = NULL;
hr = InitializeClass(pConn, L"__Namespace", &pObj);
if (FAILED(hr))
goto Exit;
hr = AddPropertyToClass(pObj, L"Name", CIM_STRING, TRUE);
hr = CSQLExecProcedure::UpdateClassBlob(pConn, 2372429868687864876, (_IWmiObject *)pObj);
((_IWmiObject *)pObj)->SetDecoration(L".", L"root");
hr = pObj->SpawnDerivedClass(0, &pDerived);
pObj->Release();
if (FAILED(hr))
goto Exit;
hr = InitializeClass(pConn, L"__Instances", &pObj);
if (FAILED(hr))
goto Exit;
hr = AddPropertyToClass(pObj, L"ClassName", CIM_STRING, TRUE);
hr = CSQLExecProcedure::UpdateClassBlob(pConn, 3373910491091605771, (_IWmiObject *)pObj);
pObj->Release();
if (FAILED(hr))
goto Exit;
hr = InitializeClass(pConn, L"__Container_Association", &pObj);
if (FAILED(hr))
goto Exit;
hr = AddPropertyToClass(pObj, L"Containee", CIM_REFERENCE, TRUE);
hr = AddPropertyToClass(pObj, L"Container", CIM_REFERENCE, TRUE);
hr = CSQLExecProcedure::UpdateClassBlob(pConn, -7316356768687527881, (_IWmiObject *)pObj);
pObj->Release();
if (FAILED(hr))
goto Exit;
// Custom repository stuff
// __SqlMappedNamespace
// __CustRepDrvrMapping
// __CustRepDrvrMappingProperty
if (pDerived)
{
VARIANT vTemp;
VariantInit(&vTemp);
vTemp.bstrVal = SysAllocString(L"__SqlMappedNamespace");
vTemp.vt = VT_BSTR;
pDerived->Put(L"__Class", 0, &vTemp, CIM_STRING);
VariantClear(&vTemp);
hr = CSQLExecProcedure::UpdateClassBlob(pConn, -7061265575274197401, (_IWmiObject *)pDerived);
pDerived->Release();
if (FAILED(hr))
goto Exit;
}
hr = InitializeClass(pConn, L"__CustRepDrvrMapping", &pObj);
if (FAILED(hr))
goto Exit;
hr = AddPropertyToClass(pObj, L"sTableName", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sPrimaryKeyCol", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sDatabaseName", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sClassName", CIM_STRING, TRUE);
hr = AddPropertyToClass(pObj, L"sScopeClass", CIM_STRING);
hr = AddPropertyToClass(pObj, L"arrProperties", CIM_OBJECT+CIM_FLAG_ARRAY, FALSE, L"object:__CustRepDrvrMappingProperty");
hr = CSQLExecProcedure::UpdateClassBlob(pConn, -539347062633018661, (_IWmiObject *)pObj);
pObj->Release();
if (FAILED(hr))
goto Exit;
hr = InitializeClass(pConn, L"__CustRepDrvrMappingProperty", &pObj);
if (FAILED(hr))
goto Exit;
hr = AddPropertyToClass(pObj, L"arrColumnNames", CIM_STRING+CIM_FLAG_ARRAY);
hr = AddPropertyToClass(pObj, L"arrForeignKeys", CIM_STRING+CIM_FLAG_ARRAY);
hr = AddPropertyToClass(pObj, L"bIsKey", CIM_BOOLEAN);
hr = AddPropertyToClass(pObj, L"bStoreAsNumber", CIM_BOOLEAN);
hr = AddPropertyToClass(pObj, L"bReadOnly", CIM_BOOLEAN);
hr = AddPropertyToClass(pObj, L"bStoreAsBlob", CIM_BOOLEAN);
hr = AddPropertyToClass(pObj, L"bDecompose", CIM_BOOLEAN);
hr = AddPropertyToClass(pObj, L"bStoreAsMofText", CIM_BOOLEAN);
hr = AddPropertyToClass(pObj, L"sPropertyName", CIM_STRING, TRUE);
hr = AddPropertyToClass(pObj, L"sTableName", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sClassTableName", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sClassDataColumn", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sClassNameColumn", CIM_STRING);
hr = AddPropertyToClass(pObj, L"sClassForeignKey", CIM_STRING);
hr = CSQLExecProcedure::UpdateClassBlob(pConn, -3130657873239620716, (_IWmiObject *)pObj);
pObj->Release();
if (FAILED(hr))
goto Exit;
}
else
hr = WBEM_E_NOT_FOUND;
if (pTemp)
fclose(pTemp);
// Get rid of it so we don't run it again.
if (SUCCEEDED(hr))
{
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"commit transaction ");
DeleteFile(sFile);
}
else
CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"rollback transaction ");
}
}
}
if (SUCCEEDED(hr))
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"exec sp_AutoDelete ");
Exit:
return hr;
}
//***************************************************************************
//
// CSQLConnCache::GetConnection
//
//***************************************************************************
HRESULT CSQLConnCache::GetConnection(CSQLConnection **ppConn, BOOL bTransacted,
BOOL bDistributed,DWORD dwTimeOutSecs)
{
HRESULT hr = WBEM_S_NO_ERROR;
bool bFound = false;
DWORD dwThreadId = GetCurrentThreadId();
CRepdrvrCritSec r (&m_cs);
static BOOL bInit = FALSE;
if (!ppConn)
return WBEM_E_INVALID_PARAMETER;
if (m_WaitQueue.size() && dwTimeOutSecs > 0)
goto Queue;
// See if there are any free connections.
// ======================================
if (m_Conns.size() > 0)
{
for (int i = 0; i < m_Conns.size(); i++)
{
CSQLConnection *pConn = m_Conns.at(i);
if (pConn)
{
COLEDBConnection *pConn2 = (COLEDBConnection *)pConn;
time_t tTemp = time(0);
if (!pConn2->m_bInUse)
{
if (!bDistributed || (dwThreadId == pConn->m_dwThreadId))
{
pConn2->m_bInUse = true;
pConn2->m_tCreateTime = time(0);
*ppConn = pConn;
bFound = true;
break;
}
}
}
}
}
// Look for any connection that has no
// thread ID and take ownership.
// ===================================
if (bDistributed && !bFound)
{
for (int i = 0; i < m_Conns.size(); i++)
{
COLEDBConnection *pConn = (COLEDBConnection *)m_Conns.at(i);
if (pConn)
{
if (!pConn->m_bInUse && !pConn->m_dwThreadId)
{
pConn->m_bInUse = true;
pConn->m_tCreateTime = time(0);
*ppConn = pConn;
bFound = true;
break;
}
}
}
}
// If there were no free connections, try and obtain a new one.
// ============================================================
if (!bFound && (m_Conns.size() < m_dwMaxNumConns))
{
IDBInitialize *pDBInit = NULL;
IDBProperties* pIDBProperties = NULL;
hr = CoCreateInstance(CLSID_SQLOLEDB, NULL, CLSCTX_INPROC_SERVER,
IID_IDBInitialize, (void**)&pDBInit);
pDBInit->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties);
CReleaseMe r1 (pIDBProperties);
hr = pIDBProperties->SetProperties(1, m_pPropSet);
hr = pDBInit->Initialize();
if (SUCCEEDED(hr))
{
COLEDBConnection *pConn2 = new COLEDBConnection(pDBInit);
CSQLConnection *pConn = (CSQLConnection *)pConn2;
if (pConn)
{
pConn2->m_bInUse = true;
pConn2->m_tCreateTime = time(0);
if (SUCCEEDED(hr))
{
ITransaction *pTrans = NULL;
IDBCreateCommand *pCmd = NULL;
IDBCreateSession *pSession = NULL;
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
if (SUCCEEDED(hr))
{
pConn2->SetSessionObj(pSession);
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
if (SUCCEEDED(hr))
{
pConn2->SetCommand(pCmd);
// Set the Session and Command objects.
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(),
L"use %s", NULL, NULL, (LPWSTR)m_sDatabaseName);
if (!bInit)
{
hr = Startup(hr, pConn, m_sDatabaseName);
if (SUCCEEDED(hr))
bInit = TRUE;
}
if (SUCCEEDED(hr))
hr = ExecInitialQueries(pDBInit, pConn);
}
}
}
if (SUCCEEDED(hr))
m_Conns.push_back(pConn);
else
{
delete pConn;
pConn = NULL;
}
}
*ppConn = pConn;
}
else
hr = WBEM_E_CONNECTION_FAILED;
}
if (SUCCEEDED(hr))
{
if (bTransacted || bDistributed)
{
COLEDBConnection *pConn2 = (COLEDBConnection *)*ppConn;
if (!pConn2->m_pTrans)
{
ITransaction *pTrans = NULL;
hr = pConn2->GetCommand()->QueryInterface(IID_ITransactionLocal,(void**) &pTrans);
if (SUCCEEDED(hr))
{
hr = ((ITransactionLocal*) pTrans)->StartTransaction(ISOLATIONLEVEL_SERIALIZABLE, 0, NULL, NULL);
pConn2->m_pTrans = pTrans;
}
}
}
}
Queue:
// Otherwise, wait for a connection to be released.
// ================================================
if (!*ppConn && (m_Conns.size() >= m_dwMaxNumConns) && dwTimeOutSecs > 0)
{
DEBUGTRACE((LOG_WBEMCORE, "WARNING: >> Number of SQL connections exceeded (%ld). Thread %ld is waiting on one to be released...\n",
m_Conns.size(), GetCurrentThreadId()));
wchar_t wTemp[30];
swprintf(wTemp, L"%ld", GetCurrentThreadId());
HANDLE hThreadEvent = CreateEvent(NULL, TRUE, FALSE, wTemp);
if (hThreadEvent != INVALID_HANDLE_VALUE)
{
m_WaitQueue.push_back(hThreadEvent);
if (WaitForSingleObject(hThreadEvent, dwTimeOutSecs*1000) == WAIT_OBJECT_0)
{
hr = GetConnection(ppConn, bTransacted, bDistributed, 0);
if (SUCCEEDED(hr))
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld obtained a connection.\n", GetCurrentThreadId()));
}
else
hr = WBEM_E_SERVER_TOO_BUSY;
}
else
hr = WBEM_E_OUT_OF_MEMORY;
// Remove ourself from the queue
// This will happen whether the GetConnection
// succeeded or failed
// ==========================================
for (int i = 0; i < m_WaitQueue.size(); i++)
{
if (hThreadEvent == m_WaitQueue.at(i))
{
m_WaitQueue.erase(&m_WaitQueue.at(i));
break;
}
}
CloseHandle(hThreadEvent);
}
if (!*ppConn && SUCCEEDED(hr))
{
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld was unable to obtain a connection.\n", GetCurrentThreadId()));
hr = WBEM_E_SERVER_TOO_BUSY;
}
return hr;
}
//***************************************************************************
//
// CSQLConnCache::ExecInitialQueries
//
//***************************************************************************
HRESULT CSQLConnCache::ExecInitialQueries(IDBInitialize *pDBInit, CSQLConnection *pConn)
{
HRESULT hr = 0;
COLEDBConnection *pConn2 = (COLEDBConnection *)pConn;
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L"set nocount on ");
// This is expensive. Only do this once per connection!
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection*)pConn)->GetCommand(), L" create table #Parents (ClassId numeric(20,0)) "
L" create table #Children (ClassId numeric(20,0), SuperClassId numeric(20,0)) "
L" create table #SubScopeIds (ID numeric(20,0)) ");
return hr;
}
//***************************************************************************
//
// CSQLExecute::GetWMIError
//
//***************************************************************************
HRESULT CSQLExecute::GetWMIError(IUnknown *pErrorObj)
{
HRESULT hr = WBEM_S_NO_ERROR;
IErrorInfo *pErrorInfo;
IErrorRecords *pErrorRecords;
ISupportErrorInfo *pSupportErrorInfo;
DWORD dwLocaleID = 1033; // TO DO: Figure this out later...
ERRORINFO ErrorInfo;
unsigned long ulNumErrorRecs;
hr = ((IUnknown *)pErrorObj)->QueryInterface(IID_ISupportErrorInfo,
(LPVOID FAR*) &pSupportErrorInfo);
CReleaseMe d (pSupportErrorInfo);
if (SUCCEEDED(hr))
{
GetErrorInfo(0, &pErrorInfo);
CReleaseMe r2 (pErrorInfo);
if (pErrorInfo)
{
pErrorInfo->QueryInterface(IID_IErrorRecords, (LPVOID FAR*) &pErrorRecords);
CReleaseMe r1 (pErrorRecords);
pErrorRecords->GetRecordCount(&ulNumErrorRecs);
DWORD dwMinor = 0;
if (ulNumErrorRecs)
{
pErrorRecords->GetBasicErrorInfo(0, &ErrorInfo);
HRESULT temp = ErrorInfo.hrError;
dwMinor = ErrorInfo.dwMinor;
switch (dwMinor)
{
case 99103:
hr = WBEM_E_ACCESS_DENIED;
break;
case 99106:
case 99107:
case 99108:
case 99109:
case 99124:
hr = WBEM_E_INVALID_PARAMETER;
break;
case 99111:
case 99112:
case 99114:
hr = WBEM_E_INVALID_PROPERTY;
break;
case 99115:
hr = WBEM_E_INVALID_QUERY;
break;
case 99116:
case 99117:
case 99118:
case 99119:
case 99120:
case 99121:
case 99122:
case 99123:
case 99127:
case 99130:
case 99131:
case 99133:
hr = WBEM_E_INVALID_OPERATION;
break;
case 99102:
case 99110:
case 99113:
case 99125:
case 99132:
case 99134:
hr = WBEM_E_ALREADY_EXISTS;
break;
case 99126:
case 99104:
case 99105:
case 99100:
case 99101:
hr = WBEM_E_INVALID_OBJECT;
break;
case 99128:
hr = WBEM_E_CLASS_HAS_INSTANCES;
break;
case 1205: // Your transaction (process ID #%d) was deadlocked with another process and has been chosen as the deadlock victim.
hr = WBEM_E_RERUN_COMMAND;
break;
case 99129:
hr = WBEM_E_CIRCULAR_REFERENCE;
break;
default:
hr = WBEM_E_INVALID_QUERY;
break;
}
if (hr == WBEM_E_INVALID_QUERY)
{
for (int i = 0; i < ulNumErrorRecs; i++)
{
IErrorInfo *pErrorInfoRec = NULL;
BSTR sSource, sDescr;
pErrorRecords->GetErrorInfo(i, dwLocaleID, &pErrorInfoRec);
CReleaseMe r (pErrorInfoRec);
sSource = NULL;
sDescr = NULL;
pErrorInfoRec->GetDescription(&sDescr);
ERRORTRACE((LOG_WBEMCORE, "SQL Error: %S\n", (const wchar_t *)sDescr));
wprintf(L"SQL Error: %s\n", (const wchar_t *)sDescr);
pErrorInfoRec->GetSource(&sSource);
CFreeMe f1 (sDescr), f2 (sSource);
SetErrorInfo(0, pErrorInfoRec);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::GetHierarchy
//
//***************************************************************************
HRESULT CSQLExecProcedure::GetHierarchy(CSQLConnection *pConn, SQL_ID dClassId)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_GetHierarchy (?, 0) }";
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 1;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
typedef struct tagSPROCPARAMS
{
DB_NUMERIC dClassId;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
CSQLExecute::SetDBNumeric(sprocparams.dClassId, dClassId);
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding,
sizeof(SPROCPARAMS), &hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
int iNum = 0;
while (iNum < 5)
{
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r2 (pIRowset);
if (SUCCEEDED(hr))
break;
else
hr = CSQLExecute::GetWMIError(pICommandText);
if (hr != WBEM_E_RERUN_COMMAND)
break;
iNum++;
}
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::GetNextUnkeyedPath
//
//***************************************************************************
HRESULT CSQLExecProcedure::GetNextUnkeyedPath(CSQLConnection *pConn, SQL_ID dClassId, _bstr_t &sNewPath)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_GetNextUnkeyedPath (?, ?) }";
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 2;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
typedef struct tagSPROCPARAMS
{
DB_NUMERIC dClassId;
BSTR wNewPath;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
CSQLExecute::SetDBNumeric(sprocparams.dClassId, dClassId);
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_WVARCHAR", L"@NewPath", 450, DBPARAMFLAGS_ISOUTPUT, 11);
ParamOrdinals[1] = 2;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(SPROCPARAMS, wNewPath), DBPARAMIO_OUTPUT, 450, DBTYPE_BSTR, 11);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(SPROCPARAMS),
&hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
CFreeMe f1 (sprocparams.wNewPath);
if (SUCCEEDED(hr))
sNewPath = (const wchar_t *)sprocparams.wNewPath;
else
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
else
hr = CSQLExecute::GetWMIError(pIAccessor);
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::GetNextKeyhole
//
//***************************************************************************
HRESULT CSQLExecProcedure::GetNextKeyhole(CSQLConnection *pConn, DWORD iPropertyId, SQL_ID &dNewId)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_GetNextKeyhole (?, ?) }";
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 2;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
typedef struct tagSPROCPARAMS
{
DB_NUMERIC dRetVal;
int iPropertyId;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
sprocparams.iPropertyId = iPropertyId;
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_NUMERIC", L"@NextID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISOUTPUT, 20);
ParamOrdinals[1] = 2;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_I4", L"@PropID", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[0] = 1;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(SPROCPARAMS, dRetVal), DBPARAMIO_OUTPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, iPropertyId), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(SPROCPARAMS),
&hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
dNewId = CSQLExecute::GetInt64(&(sprocparams.dRetVal));
else
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
else
hr = CSQLExecute::GetWMIError(pIAccessor);
}
}
}
}
return hr;
}
HRESULT CSQLExecProcedure::GetObjectIdByPath (CSQLConnection *pConn, LPCWSTR lpPath,
SQL_ID &dObjectId, SQL_ID &dClassId, SQL_ID *dScopeId, BOOL *bDeleted)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_GetInstanceID (?, ?, ?, ?) }";
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pIDBCreate = NULL;
IDBCreateCommand *pIDBCreateCommand = NULL;
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 4;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
typedef struct tagSPROCPARAMS
{
BSTR sPath;
DB_NUMERIC dObjectId;
DB_NUMERIC dClassId;
DB_NUMERIC dScopeId;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
sprocparams.sPath = SysAllocString(lpPath);
CFreeMe f1 (sprocparams.sPath);
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pIDBCreate);
CReleaseMe r1 (pIDBCreate);
if (SUCCEEDED(hr))
{
hr = pIDBCreate->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pIDBCreateCommand);
CReleaseMe r2 (pIDBCreateCommand);
if (SUCCEEDED(hr))
{
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r3 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_BSTR", L"@ObjectKey", 450, DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_NUMERIC", L"@ObjectId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISOUTPUT, 20);
ParamOrdinals[1] = 2;
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_NUMERIC", L"@ClassId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISOUTPUT, 20);
ParamOrdinals[2] = 3;
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_NUMERIC", L"@ScopeId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISOUTPUT, 20);
ParamOrdinals[3] = 4;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r4 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, sPath), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(SPROCPARAMS, dObjectId), DBPARAMIO_OUTPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(SPROCPARAMS, dClassId), DBPARAMIO_OUTPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(SPROCPARAMS, dScopeId), DBPARAMIO_OUTPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r5 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(SPROCPARAMS),
&hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r6 (pIRowset);
if (SUCCEEDED(hr))
{
dObjectId = CSQLExecute::GetInt64(&(sprocparams.dObjectId));
dClassId = CSQLExecute::GetInt64(&(sprocparams.dClassId));
if (dScopeId)
*dScopeId = CSQLExecute::GetInt64(&(sprocparams.dScopeId));
}
else
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
else
hr = CSQLExecute::GetWMIError(pIAccessor);
}
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::DeleteProperty
//
//***************************************************************************
HRESULT CSQLExecProcedure::DeleteProperty(CSQLConnection *pConn, DWORD iPropertyId)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_DeleteClassData (?) }";
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 1;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
typedef struct tagSPROCPARAMS
{
int iPropertyId;
} SPROCPARAMS;
SPROCPARAMS sprocparams = {iPropertyId};
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_I4", L"@PropertyID", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[0] = 1;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, iPropertyId), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 20);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding,
sizeof(SPROCPARAMS), &hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (FAILED(hr))
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::DeleteInstanceData
//
//***************************************************************************
HRESULT CSQLExecProcedure::DeleteInstanceData (CSQLConnection *pConn, SQL_ID dObjectId,
DWORD iPropertyId, DWORD iPos)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_DeleteInstanceData (?, ?, ?) }";
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 3;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
typedef struct tagSPROCPARAMS
{
DB_NUMERIC dObjectId;
int iPropertyId;
int iPos;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
sprocparams.iPropertyId = iPropertyId;
sprocparams.iPos = iPos;
CSQLExecute::SetDBNumeric(sprocparams.dObjectId, dObjectId);
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ObjectID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_I4", L"@PropertyID", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[1] = 2;
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_I4", L"@ArrayPos", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[2] = 3;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, dObjectId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(SPROCPARAMS, iPropertyId), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(SPROCPARAMS, iPos), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding,
sizeof(SPROCPARAMS), &hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (FAILED(hr))
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertClass
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertClass (CSQLConnection *pConn, LPCWSTR lpClassName, LPCWSTR lpObjectKey,
LPCWSTR lpObjectPath, SQL_ID dScopeID,
SQL_ID dParentClassId, SQL_ID dDynastyId, DWORD iState, BYTE *pClassBuff, DWORD dwClassBuffLen,
DWORD iClassFlags, DWORD iInsertFlags, SQL_ID &dNewId)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
const WCHAR *pszCmd = L"{call sp_InsertClass (?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?) }";
const ULONG nParams = 10;
STRUCTINSERTCLASS params;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_INSERT_CLASS);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_INSERT_CLASS);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_INSERT_CLASS);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_INSERT_CLASS);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
dNewId = CRC64::GenerateHashValue(lpObjectKey);
CSQLExecute::SetDBNumeric(params.dRetVal, dNewId);
params.sClassName = SysAllocString(lpClassName);
params.sObjectKey = SysAllocString(lpObjectKey);
params.sObjectPath = SysAllocString(lpObjectPath);
params.pClassBuff = pClassBuff;
CSQLExecute::SetDBNumeric(params.dScopeID, dScopeID);
CSQLExecute::SetDBNumeric(params.dParentClassId, dParentClassId);
params.iClassState = iState;
params.iClassFlags = iClassFlags;
params.iInsertFlags = iInsertFlags;
CFreeMe f1 (params.sClassName), f2 (params.sObjectKey), f3 (params.sObjectPath);
for (i = 0; i < nParams; i++)
ParamOrdinals[i] = i+1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_BSTR", L"@ClassName", 450, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_BSTR", L"@ObjectKey", 450, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_BSTR", L"@ObjectPath", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_NUMERIC", L"@ScopeObjID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[4], L"DBTYPE_NUMERIC", L"@ParentID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[5], L"DBTYPE_I4", L"@ClassState", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[6], L"DBTYPE_LONGVARBINARY", L"@ClassBuffer", 0, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[7], L"DBTYPE_I4", L"@ClassFlags", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[8], L"DBTYPE_I4", L"@InsertFlags", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[9], L"DBTYPE_NUMERIC", L"@ObjectId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTINSERTCLASS, sClassName), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTINSERTCLASS, sObjectKey), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(STRUCTINSERTCLASS, sObjectPath), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(STRUCTINSERTCLASS, dScopeID), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[4], 5, offsetof(STRUCTINSERTCLASS, dParentClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[5], 6, offsetof(STRUCTINSERTCLASS, iClassState), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[6], 7, offsetof(STRUCTINSERTCLASS, pClassBuff), DBPARAMIO_INPUT, 0, DBTYPE_BYTES, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[7], 8, offsetof(STRUCTINSERTCLASS, iClassFlags), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[8], 9, offsetof(STRUCTINSERTCLASS, iInsertFlags), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[9], 10, offsetof(STRUCTINSERTCLASS, dRetVal), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_INSERT_CLASS, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_INSERT_CLASS, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_INSERT_CLASS, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTINSERTCLASS),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_INSERT_CLASS, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &params;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
int iNum = 0;
while (iNum < 5)
{
// Try this query up to 5 times, in case we get a deadlock.
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
break;
else
hr = CSQLExecute::GetWMIError(pICommandText);
if (hr != WBEM_E_RERUN_COMMAND)
break;
iNum++;
Sleep(iNum*100);
}
if(SUCCEEDED(hr))
{
wchar_t wBuff[256];
swprintf(wBuff, L"select ClassBlob from ClassMap "
L" where ClassId = %I64d", dNewId);
if (SUCCEEDED(hr))
{
hr = CSQLExecute::WriteImageValue
(((COLEDBConnection *)pConn)->GetCommand(), wBuff, 1, pClassBuff, dwClassBuffLen);
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertClassData
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertClassData (CSQLConnection *pConn, IWbemClassObject *pObj, CSchemaCache *pCache, SQL_ID dScopeId,
SQL_ID dClassId, LPCWSTR lpPropName,
DWORD CIMType, DWORD StorageType,LPCWSTR lpValue, SQL_ID dRefClassId, DWORD iPropID,
DWORD iFlags, DWORD iFlavor, BOOL iSkipValid, DWORD &iNewPropId, SQL_ID dOrigClassId,
BOOL *bIsKey)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
const WCHAR *pszCmd = L"{? = call sp_InsertClassData (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) }";
const ULONG nParams = 12;
BOOL bLocal = FALSE;
BOOL bKey = FALSE;
if (pCache)
pCache->IsKey(dClassId, iNewPropId, bLocal);
if (iFlags & REPDRVR_FLAG_KEY)
{
if (!bKey)
bKey = TRUE;
else if (bKey && !bLocal)
bKey = FALSE;
}
if (bIsKey)
*bIsKey = bKey;
STRUCTINSERTCLASSDATA params;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_INSERT_CLASSDATA);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_INSERT_CLASSDATA);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_INSERT_CLASSDATA);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_INSERT_CLASSDATA);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
bool bStoreTextAsImage = false;
params.sPropName = SysAllocString(lpPropName);
if (lpValue)
params.sValue = OLEDBTruncateLongText(lpValue, SQL_STRING_LIMIT, bStoreTextAsImage);
else
params.sValue = SysAllocString(L"");
CFreeMe f1 (params.sPropName), f2 (params.sValue);
CSQLExecute::SetDBNumeric(params.dClassId, dClassId);
CSQLExecute::SetDBNumeric(params.dRefClassId, dRefClassId);
params.iCimType = CIMType;
params.iStorageType = StorageType;
params.iPropID = iPropID;
params.iFlags = iFlags;
params.iFlavor = iFlavor;
params.iRetVal = 0;
params.iKnownID = iNewPropId;
params.bIsKey = bKey;
for (i = 0; i < nParams; i++)
ParamOrdinals[i] = i+1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_I4", L"ReturnVal", sizeof(DWORD), DBPARAMFLAGS_ISOUTPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_BSTR", L"@PropName", 450, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_I4", L"@CIMType", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[4], L"DBTYPE_I4", L"@StorageType", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[5], L"DBTYPE_BSTR", L"@Value", 450, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[6], L"DBTYPE_NUMERIC", L"@RefClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[7], L"DBTYPE_I4", L"@PropID", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[8], L"DBTYPE_I4", L"@Flags", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[9], L"DBTYPE_I4", L"@Flavor", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[10], L"DBTYPE_I4", L"@PropertyId", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[11], L"DBTYPE_BOOL", L"@IsKey", sizeof(BOOL), DBPARAMFLAGS_ISINPUT, 1);
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTINSERTCLASSDATA, iRetVal), DBPARAMIO_OUTPUT, sizeof(DWORD), DBTYPE_I4, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTINSERTCLASSDATA, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(STRUCTINSERTCLASSDATA, sPropName), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(STRUCTINSERTCLASSDATA, iCimType), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[4], 5, offsetof(STRUCTINSERTCLASSDATA, iStorageType), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[5], 6, offsetof(STRUCTINSERTCLASSDATA, sValue), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[6], 7, offsetof(STRUCTINSERTCLASSDATA, dRefClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[7], 8, offsetof(STRUCTINSERTCLASSDATA, iPropID), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[8], 9, offsetof(STRUCTINSERTCLASSDATA, iFlags), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[9], 10, offsetof(STRUCTINSERTCLASSDATA, iFlavor), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[10], 11, offsetof(STRUCTINSERTCLASSDATA, iKnownID), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[11], 12, offsetof(STRUCTINSERTCLASSDATA, bIsKey), DBPARAMIO_INPUT, sizeof(BOOL), DBTYPE_BOOL, 1);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_INSERT_CLASSDATA, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_INSERT_CLASSDATA, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_INSERT_CLASSDATA, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTINSERTCLASSDATA),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_INSERT_CLASSDATA, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &params;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
int iNum = 0;
while (iNum < 5)
{
// Try this query up to 5 times, in case we get a deadlock.
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
{
iNewPropId = params.iRetVal;
break;
}
else
hr = CSQLExecute::GetWMIError(pICommandText);
if (hr != WBEM_E_RERUN_COMMAND)
break;
iNum++;
Sleep(iNum*100);
}
}
// If we need to store the default value as an image,
// do it now.
if (bStoreTextAsImage && lpValue)
{
hr = InsertBlobData (pConn, 1, dClassId, iNewPropId, NULL, 0, 0);
wchar_t wSQL[1024];
swprintf(wSQL, L"select PropertyImageValue from ClassImages where ObjectId = %I64d and PropertyId = %ld",
dClassId, iNewPropId);
hr = CSQLExecute::WriteImageValue(pCmd, wSQL, 1, (BYTE *)lpValue, wcslen(lpValue)*2);
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertBlobData
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertBlobData (CSQLConnection *pConn, SQL_ID dClassId, SQL_ID dObjectId,
DWORD iPropertyId, BYTE *pImage, DWORD iPos, DWORD dwNumBytes)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
const WCHAR *pszCmd = L"{call sp_InsertInstanceBlobData (?, ?, ?, ?, ?) }";
const ULONG nParams = 5;
STRUCTINSERTBLOB params;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_INSERT_BLOBDATA);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_INSERT_BLOBDATA);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_INSERT_BLOBDATA);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_INSERT_BLOBDATA);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
CSQLExecute::SetDBNumeric(params.dClassId, dClassId);
CSQLExecute::SetDBNumeric(params.dObjectId, dObjectId);
params.iPropertyId = iPropertyId;
params.iPos = iPos;
params.pImage = pImage;
for (i = 0; i < nParams; i++)
ParamOrdinals[i] = i+1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_NUMERIC", L"@ObjectID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_I4", L"@PropertyID", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_LONGVARBINARY", L"@Value", dwNumBytes, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[4], L"DBTYPE_I4", L"@ArrayPos", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 11);
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTINSERTBLOB, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTINSERTBLOB, dObjectId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(STRUCTINSERTBLOB, iPropertyId), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(STRUCTINSERTBLOB, pImage), DBPARAMIO_INPUT, dwNumBytes, DBTYPE_BYTES, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[4], 5, offsetof(STRUCTINSERTBLOB, iPos), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_INSERT_BLOBDATA, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_INSERT_BLOBDATA, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_INSERT_BLOBDATA, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTINSERTBLOB),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_INSERT_BLOBDATA, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &params;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (FAILED(hr))
hr = CSQLExecute::GetWMIError(pICommandText);
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertPropertyBatch
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertPropertyBatch (CSQLConnection *pConn, LPCWSTR lpObjectKey,
LPCWSTR lpPath, LPCWSTR lpClassName, SQL_ID dClassId,
SQL_ID dScopeId, DWORD iFlags,
InsertPropValues *pVals, DWORD iNumVals,
SQL_ID &dNewObjectId)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
const WCHAR *pszCmd = L"{call sp_BatchInsertProperty (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
L"?, ?, ?, ?, ?, ?, ?, ?, ?, ?) }";
const ULONG nParams = 23;
STRUCTINSERTPROPBATCH sp;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_INSERT_PROPBATCH);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_INSERT_PROPBATCH);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_INSERT_PROPBATCH);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_INSERT_PROPBATCH);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
dNewObjectId = CRC64::GenerateHashValue(lpObjectKey);
CSQLExecute::SetDBNumeric(sp.dObjectId, dNewObjectId);
CSQLExecute::SetDBNumeric(sp.dClassId, dClassId);
CSQLExecute::SetDBNumeric(sp.dScopeId, dScopeId);
sp.sObjectPath = SysAllocString(lpPath);
sp.sObjectKey = SysAllocString(lpObjectKey);
sp.bInit = TRUE;
for (i = 0; i < 5; i++)
sp.sPropValue[i] = NULL;
sp.iInsertFlags = iFlags;
// Grab only the first part of the key string - up to the class name.
wchar_t *pTmp = wcsstr(lpObjectKey, lpClassName);
if (pTmp)
{
int iLen = pTmp - lpObjectKey;
wchar_t *pNew = new wchar_t [iLen+1];
CDeleteMe <wchar_t> d (pNew);
if (pNew)
{
wcsncpy(pNew, lpObjectKey, iLen);
pNew[iLen] = L'\0';
sp.sCompKey = SysAllocString(pNew);
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else
{
wchar_t *pNew = new wchar_t [ wcslen(lpObjectKey) + 2];
CDeleteMe <wchar_t> d (pNew);
if (pNew)
{
swprintf(pNew, L"%s?", lpObjectKey);
sp.sCompKey = SysAllocString(pNew);
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
CFreeMe f1 (sp.sObjectPath), f2 (sp.sObjectKey), f3 (sp.sCompKey);
for (i = 0; i < nParams; i++)
ParamOrdinals[i] = i+1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ObjectId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_BSTR", L"@ObjectKey", 450, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_BSTR", L"@ObjectPath", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[4], L"DBTYPE_NUMERIC", L"@ScopeID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[5], L"DBTYPE_I4", L"@InsertFlags", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[6], L"DBTYPE_BOOL", L"@Init", sizeof(BOOL), DBPARAMFLAGS_ISINPUT, 1);
CSQLExecute::SetParamBindInfo(ParamBindInfo[7], L"DBTYPE_I4", L"@PropID1", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[8], L"DBTYPE_BSTR", L"@PropValue1", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[9], L"DBTYPE_I4", L"@PropPos1", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[10], L"DBTYPE_I4", L"@PropID2", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[11], L"DBTYPE_BSTR", L"@PropValue2", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[12], L"DBTYPE_I4", L"@PropPos2", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[13], L"DBTYPE_I4", L"@PropID3", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[14], L"DBTYPE_BSTR", L"@PropValue3", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[15], L"DBTYPE_I4", L"@PropPos3", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[16], L"DBTYPE_I4", L"@PropID4", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[17], L"DBTYPE_BSTR", L"@PropValue4", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[18], L"DBTYPE_I4", L"@PropPos4", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[19], L"DBTYPE_I4", L"@PropID5", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[20], L"DBTYPE_BSTR", L"@PropValue5", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[21], L"DBTYPE_I4", L"@PropPos5", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[22], L"DBTYPE_BSTR", L"@CompKey", 450, DBPARAMFLAGS_ISINPUT, 11);
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTINSERTPROPBATCH, dObjectId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTINSERTPROPBATCH, sObjectKey), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(STRUCTINSERTPROPBATCH, sObjectPath), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(STRUCTINSERTPROPBATCH, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[4], 5, offsetof(STRUCTINSERTPROPBATCH, dScopeId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[5], 6, offsetof(STRUCTINSERTPROPBATCH, iInsertFlags), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[6], 7, offsetof(STRUCTINSERTPROPBATCH, bInit), DBPARAMIO_INPUT, sizeof(BOOL), DBTYPE_BOOL, 1);
CSQLExecute::SetBindingInfo(&acDBBinding[7], 8, offsetof(STRUCTINSERTPROPBATCH, iPropId[0]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[8], 9, offsetof(STRUCTINSERTPROPBATCH, sPropValue[0]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[9], 10, offsetof(STRUCTINSERTPROPBATCH, iPos[0]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[10], 11, offsetof(STRUCTINSERTPROPBATCH, iPropId[1]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[11], 12, offsetof(STRUCTINSERTPROPBATCH, sPropValue[1]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[12], 13, offsetof(STRUCTINSERTPROPBATCH, iPos[1]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[13], 14, offsetof(STRUCTINSERTPROPBATCH, iPropId[2]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[14], 15, offsetof(STRUCTINSERTPROPBATCH, sPropValue[2]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[15], 16, offsetof(STRUCTINSERTPROPBATCH, iPos[2]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[16], 17, offsetof(STRUCTINSERTPROPBATCH, iPropId[3]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[17], 18, offsetof(STRUCTINSERTPROPBATCH, sPropValue[3]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[18], 19, offsetof(STRUCTINSERTPROPBATCH, iPos[3]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[19], 20, offsetof(STRUCTINSERTPROPBATCH, iPropId[4]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[20], 21, offsetof(STRUCTINSERTPROPBATCH, sPropValue[4]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[21], 22, offsetof(STRUCTINSERTPROPBATCH, iPos[4]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[22], 23, offsetof(STRUCTINSERTPROPBATCH, sCompKey), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_INSERT_PROPBATCH, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_INSERT_PROPBATCH, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_INSERT_PROPBATCH, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTINSERTPROPBATCH),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_INSERT_PROPBATCH, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &sp;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
i = 0;
int j = 0;
while (TRUE)
{
// Set 5 parameters at a time.
for (j = 0; j < 5 && i < iNumVals; i++, j++)
{
SysFreeString(sp.sPropValue[j]);
sp.iPropId[j] = pVals[i].iPropID;
if (pVals[i].pRefKey != NULL)
{
// We need to format the reference key and original value into this parameter.
LPWSTR lpTemp = pVals[i].pValue;
pVals[i].pValue = new wchar_t [wcslen(pVals[i].pValue) + wcslen(pVals[i].pRefKey) + 2];
if (pVals[i].pValue)
swprintf(pVals[i].pValue, L"%s?%s", lpTemp, pVals[i].pRefKey);
delete lpTemp;
}
sp.sPropValue[j] = OLEDBTruncateLongText(pVals[i].pValue, SQL_STRING_LIMIT, pVals[i].bLong);
sp.iPos[j] = pVals[i].iPos;
}
// Clear other values
for (; ((j % 5) || j == 0); j++)
{
sp.iPropId[j] = 0;
if (sp.sPropValue[j])
SysFreeString(sp.sPropValue[j]);
sp.sPropValue[j] = SysAllocString(L"");
sp.iPos[j] = 0;
}
int iNum = 0;
while (iNum < 5)
{
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
break;
else
hr = CSQLExecute::GetWMIError(pICommandText);
if (hr != WBEM_E_RERUN_COMMAND)
break;
iNum++;
Sleep(iNum*100);
}
if (FAILED(hr) || i >= iNumVals)
break;
sp.bInit = FALSE;
sp.iInsertFlags = 0;
}
}
for (i = 0; i < 5; i++)
SysFreeString(sp.sPropValue[i]);
for (i = 0; i < iNumVals; i++)
{
// If our text was truncated, we need to store it as an image.
if (pVals[i].bLong)
{
if (pVals[i].pValue && wcslen(pVals[i].pValue)*2)
{
hr = InsertBlobData (pConn, dClassId, dNewObjectId, pVals[i].iPropID, NULL, 0, 0);
wchar_t wSQL[1024];
swprintf(wSQL, L"select PropertyImageValue from ClassImages where ObjectId = %I64d and PropertyId = %ld",
dNewObjectId, pVals[i].iPropID);
hr = CSQLExecute::WriteImageValue(pCmd, wSQL, 1, (BYTE *)pVals[i].pValue, wcslen(pVals[i].pValue)*2+2);
}
else
{
hr = InsertBlobData (pConn, dClassId, dNewObjectId, pVals[i].iPropID, NULL, 0, 0);
}
}
delete pVals[i].pValue;
delete pVals[i].pRefKey;
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertBatch
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertBatch (CSQLConnection *pConn, SQL_ID dObjectId, SQL_ID dScopeId, SQL_ID dClassId,
InsertQfrValues *pVals, DWORD iNumVals)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
// Batch & execute if iNumVals > 5
const WCHAR *pszCmd = L"{call sp_BatchInsert (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
L"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) }";
const ULONG nParams = 28;
STRUCTINSERTBATCH sp;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_INSERT_BATCH);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_INSERT_BATCH);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_INSERT_BATCH);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_INSERT_BATCH);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
CSQLExecute::SetDBNumeric(sp.dObjectId, dObjectId);
CSQLExecute::SetDBNumeric(sp.dScopeId, dScopeId);
CSQLExecute::SetDBNumeric(sp.dClassId, dClassId);
for (i = 0; i < 5; i++)
sp.sPropValue[i] = NULL;
for (i = 0; i < nParams; i++)
ParamOrdinals[i] = i+1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ObjectId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_NUMERIC", L"@ScopeID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_I4", L"@QfrID1", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[4], L"DBTYPE_BSTR", L"@QfrValue1", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[5], L"DBTYPE_I4", L"@Flavor1", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[6], L"DBTYPE_I4", L"@PropID1", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[7], L"DBTYPE_I4", L"@QfrPos1", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[8], L"DBTYPE_I4", L"@QfrID2", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[9], L"DBTYPE_BSTR", L"@QfrValue2", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[10], L"DBTYPE_I4", L"@Flavor2", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[11], L"DBTYPE_I4", L"@PropID2", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[12], L"DBTYPE_I4", L"@QfrPos2", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[13], L"DBTYPE_I4", L"@QfrID3", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[14], L"DBTYPE_BSTR", L"@QfrValue3", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[15], L"DBTYPE_I4", L"@Flavor3", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[16], L"DBTYPE_I4", L"@PropID3", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[17], L"DBTYPE_I4", L"@QfrPos3", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[18], L"DBTYPE_I4", L"@QfrID4", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[19], L"DBTYPE_BSTR", L"@QfrValue4", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[20], L"DBTYPE_I4", L"@Flavor4", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[21], L"DBTYPE_I4", L"@PropID4", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[22], L"DBTYPE_I4", L"@QfrPos4", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[23], L"DBTYPE_I4", L"@QfrID5", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[24], L"DBTYPE_BSTR", L"@QfrValue5", 4000, DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[25], L"DBTYPE_I4", L"@Flavor5", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[26], L"DBTYPE_I4", L"@PropID5", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
CSQLExecute::SetParamBindInfo(ParamBindInfo[27], L"DBTYPE_I4", L"@QfrPos5", sizeof(DWORD), DBPARAMFLAGS_ISINPUT, 11);
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTINSERTBATCH, dObjectId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTINSERTBATCH, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(STRUCTINSERTBATCH, dScopeId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(STRUCTINSERTBATCH, iPropId[0]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[4], 5, offsetof(STRUCTINSERTBATCH, sPropValue[0]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[5], 6, offsetof(STRUCTINSERTBATCH, iFlavor[0]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[6], 7, offsetof(STRUCTINSERTBATCH, iQfrId[0]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[7], 8, offsetof(STRUCTINSERTBATCH, iPos[0]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[8], 9, offsetof(STRUCTINSERTBATCH, iPropId[1]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[9], 10, offsetof(STRUCTINSERTBATCH, sPropValue[1]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[10], 11, offsetof(STRUCTINSERTBATCH, iFlavor[1]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[11], 12, offsetof(STRUCTINSERTBATCH, iQfrId[1]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[12], 13, offsetof(STRUCTINSERTBATCH, iPos[1]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[13], 14, offsetof(STRUCTINSERTBATCH, iPropId[2]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[14], 15, offsetof(STRUCTINSERTBATCH, sPropValue[2]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[15], 16, offsetof(STRUCTINSERTBATCH, iFlavor[2]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[16], 17, offsetof(STRUCTINSERTBATCH, iQfrId[2]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[17], 18, offsetof(STRUCTINSERTBATCH, iPos[2]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[18], 19, offsetof(STRUCTINSERTBATCH, iPropId[3]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[19], 20, offsetof(STRUCTINSERTBATCH, sPropValue[3]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[20], 21, offsetof(STRUCTINSERTBATCH, iFlavor[3]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[21], 22, offsetof(STRUCTINSERTBATCH, iQfrId[3]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[22], 23, offsetof(STRUCTINSERTBATCH, iPos[3]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[23], 24, offsetof(STRUCTINSERTBATCH, iPropId[4]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[24], 25, offsetof(STRUCTINSERTBATCH, sPropValue[4]), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[25], 26, offsetof(STRUCTINSERTBATCH, iFlavor[4]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[26], 27, offsetof(STRUCTINSERTBATCH, iQfrId[4]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[27], 28, offsetof(STRUCTINSERTBATCH, iPos[4]), DBPARAMIO_INPUT, sizeof(DWORD), DBTYPE_I4, 11);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_INSERT_BATCH, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_INSERT_BATCH, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_INSERT_BATCH, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTINSERTBATCH),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_INSERT_BATCH, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &sp;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
i = 0;
int j = 0;
while (TRUE)
{
// Set 5 parameters at a time.
for (j = 0; j < 5 && i < iNumVals; i++, j++)
{
if (pVals[i].pRefKey != NULL)
{
// We need to format the reference key and original value into this parameter.
LPWSTR lpTemp = pVals[i].pValue;
pVals[i].pValue = new wchar_t [wcslen(pVals[i].pValue) + wcslen(pVals[i].pRefKey) + 2];
if (pVals[i].pValue)
swprintf(pVals[i].pValue, L"%s?%s", lpTemp, pVals[i].pRefKey);
delete lpTemp;
}
SysFreeString(sp.sPropValue[j]);
sp.iPropId[j] = pVals[i].iPropID;
sp.sPropValue[j] = OLEDBTruncateLongText(pVals[i].pValue, SQL_STRING_LIMIT, pVals[i].bLong);
sp.iPos[j] = pVals[i].iPos;
sp.iFlavor[j] = pVals[i].iFlavor;
sp.iQfrId[j] = pVals[i].iQfrID;
}
// Clear other values
for (; ((j % 5) || j == 0); j++)
{
sp.iPropId[j] = 0;
if (sp.sPropValue[j])
SysFreeString(sp.sPropValue[j]);
sp.sPropValue[j] = SysAllocString(L"");
sp.iPos[j] = 0;
sp.iFlavor[j] = 0;
sp.iQfrId[j] = 0;
}
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (FAILED(hr))
hr = CSQLExecute::GetWMIError(pICommandText);
if (FAILED(hr) || i >= iNumVals)
break;
}
}
for (i = 0; i < 5; i++)
SysFreeString(sp.sPropValue[i]);
// If our text was truncated, we need to store it as an image.
for (i = 0; i < iNumVals; i++)
{
if (pVals[i].bLong)
{
if (pVals[i].pValue && wcslen(pVals[i].pValue)*2)
{
hr = InsertBlobData (pConn, dClassId, dObjectId, pVals[i].iPropID, NULL, 0, 0);
wchar_t wSQL[1024];
swprintf(wSQL, L"select PropertyImageValue from ClassImages where ObjectId = %I64d and PropertyId = %ld",
dObjectId, pVals[i].iPropID);
hr = CSQLExecute::WriteImageValue(pCmd, wSQL, 1, (BYTE *)pVals[i].pValue, wcslen(pVals[i].pValue)*2+2);
}
else
{
hr = InsertBlobData (pConn, dClassId, dObjectId, pVals[i].iPropID, NULL, 0, 0);
}
}
delete pVals[i].pValue;
delete pVals[i].pRefKey;
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::GetClassInfo
//
//***************************************************************************
HRESULT CSQLExecProcedure::GetClassInfo (CSQLConnection *pConn, SQL_ID dClassId, SQL_ID &dSuperClassId, BYTE **pBuffer, DWORD &dwBuffLen)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
const WCHAR *pszCmd = L"{call sp_GetClassInfo (?) }";
const ULONG nParams = 1;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_GETCLASSOBJECT);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_GETCLASSOBJECT);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_GETCLASSOBJECT);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_GETCLASSOBJECT);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
STRUCTHASINSTANCES params;
CSQLExecute::SetDBNumeric(params.dClassId, dClassId);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ClassId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTHASINSTANCES, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_GETCLASSOBJECT, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_GETCLASSOBJECT, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_GETCLASSOBJECT, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTHASINSTANCES),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_GETCLASSOBJECT, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &params;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
{
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
IMalloc *pMalloc = NULL;
CoGetMalloc(MEMCTX_TASK, &pMalloc);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, pMalloc, &pRow, vTemp);
if (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
dSuperClassId = _wtoi64(vTemp.bstrVal);
hr = CSQLExecute::ReadImageValue (pIRowset, 2, &pRow, pBuffer, dwBuffLen);
pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
}
pMalloc->Release();
}
else
hr = CSQLExecute::GetWMIError(pICommandText);
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::HasInstances
//
//***************************************************************************
HRESULT CSQLExecProcedure::HasInstances(CSQLConnection *pConn, SQL_ID dClassId, SQL_ID *pDerivedIds, DWORD iNumDerived, BOOL &bInstancesExist)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
bInstancesExist = FALSE;
const WCHAR *pszCmd = L"{call sp_HasInstances (?, ?) }";
const ULONG nParams = 2;
STRUCTHASINSTANCES params;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_HAS_INSTANCES);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_HAS_INSTANCES);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_HAS_INSTANCES);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_HAS_INSTANCES);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
CSQLExecute::SetDBNumeric(params.dClassId, dClassId);
params.dwHasInst = 0;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ClassId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_I4", L"@HasInst", sizeof(DWORD), DBPARAMFLAGS_ISOUTPUT, 11);
ParamOrdinals[1] = 2;
// Instantiate any of the interfaces that don't exist already.
// and stick them in the cache.
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTHASINSTANCES, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTHASINSTANCES, dwHasInst), DBPARAMIO_OUTPUT, sizeof(DWORD), DBTYPE_I4, 11);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_HAS_INSTANCES, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_HAS_INSTANCES, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_HAS_INSTANCES, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTHASINSTANCES),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_HAS_INSTANCES, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &params;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
{
bInstancesExist = params.dwHasInst;
}
else
hr = CSQLExecute::GetWMIError(pICommandText);
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::CheckKeyMigration
//
//***************************************************************************
HRESULT CSQLExecProcedure::CheckKeyMigration(CSQLConnection *pConn, LPWSTR lpObjectKey, LPWSTR lpClassName, SQL_ID dClassId,
SQL_ID dScopeID, SQL_ID *pIDs, DWORD iNumIDs)
{
HRESULT hr = WBEM_S_NO_ERROR;
// Strip the classname out of the key string,
// and send it to the procedure to check for existing key combinations in this class hierarchy.
// CREATE PROCEDURE sp_CheckKeyMigration @ScopeID numeric, @ClassID numeric, @KeyString nvarchar(450), @RetVal int output
const WCHAR *pszCmd = L"{call sp_CheckKeyMigration (?, ?, ?, ?) }";
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 4;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
typedef struct tagSPROCPARAMS
{
DB_NUMERIC dClassId;
DB_NUMERIC dScopeId;
BSTR sKeyString;
DWORD dwRetVal;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
CSQLExecute::SetDBNumeric(sprocparams.dClassId, dClassId);
CSQLExecute::SetDBNumeric(sprocparams.dScopeId, dScopeID);
// Grab only the first part of the key string - up to the class name.
wchar_t *pTmp = wcsstr(lpObjectKey, lpClassName);
if (pTmp)
{
int iLen = pTmp - lpObjectKey;
wchar_t *pNew = new wchar_t [iLen+1];
CDeleteMe <wchar_t> d (pNew);
if (pNew)
{
wcsncpy(pNew, lpObjectKey, iLen);
pNew[iLen] = L'\0';
sprocparams.sKeyString = SysAllocString(pNew);
}
}
else
sprocparams.sKeyString = SysAllocString(lpObjectKey);
CFreeMe f1 (sprocparams.sKeyString);
hr = pCmd->CreateCommand(NULL, IID_ICommandText, (IUnknown**) &pICommandText);
CReleaseMe r1(pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ScopeID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_NUMERIC", L"@ClassID", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[1] = 2;
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_BSTR", L"@KeyString", 450, DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[2] = 3;
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_I4", L"@RetVal", sizeof(DWORD), DBPARAMFLAGS_ISOUTPUT, 11);
ParamOrdinals[3] = 4;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, dScopeId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(SPROCPARAMS, dClassId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(SPROCPARAMS, sKeyString), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(SPROCPARAMS, dwRetVal), DBPARAMIO_OUTPUT, sizeof(DWORD), DBTYPE_I4, 11);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(SPROCPARAMS),
&hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
{
int iRet = sprocparams.dwRetVal;
if (iRet == 1)
hr = WBEM_E_INVALID_OPERATION;
}
else
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
else
hr = CSQLExecute::GetWMIError(pIAccessor);
}
}
}
}
return hr;
}
HRESULT CSQLExecProcedure::NeedsToCheckKeyMigration(BOOL &bCheck)
{
bCheck = FALSE;
return 0;
}
//***************************************************************************
//
// CSQLExecProcedure::ObjectExists
//
//***************************************************************************
HRESULT CSQLExecProcedure::ObjectExists (CSQLConnection *pConn, SQL_ID dId, BOOL &bExists,
SQL_ID *dClassId, SQL_ID *dScopeId, BOOL bDeletedOK)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pConn || !((COLEDBConnection*)pConn)->GetDBInitialize())
return WBEM_E_INVALID_PARAMETER;
const WCHAR *pszCmd = L"{call sp_InstanceExists (?, ?, ?, ?) }";
const ULONG nParams = 4;
STRUCTOBJECTEXISTS params;
IDBInitialize *pDBInit = ((COLEDBConnection*)pConn)->GetDBInitialize();
IDBCreateSession *pSession = ((COLEDBConnection*)pConn)->GetSessionObj();
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = ((COLEDBConnection *)pConn)->GetCommandWithParams(SQL_POS_OBJECTEXISTS);
ICommandText *pICommandText = ((COLEDBConnection *)pConn)->GetCommandText(SQL_POS_OBJECTEXISTS);
IAccessor *pIAccessor = ((COLEDBConnection*)pConn)->GetIAccessor(SQL_POS_OBJECTEXISTS);
HACCESSOR hAccessor = ((COLEDBConnection*)pConn)->GetAccessor(SQL_POS_OBJECTEXISTS);
IRowset *pIRowset = NULL;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
CSQLExecute::SetDBNumeric(params.dClassId, 0);
CSQLExecute::SetDBNumeric(params.dObjectId, dId);
params.bExists = 0;
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ObjectId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_BOOL", L"@Exists", sizeof(BOOL), DBPARAMFLAGS_ISOUTPUT, 1);
ParamOrdinals[1] = 2;
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_NUMERIC", L"@ClassId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISOUTPUT, 20);
ParamOrdinals[2] = 3;
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_NUMERIC", L"@ScopeId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISOUTPUT, 20);
ParamOrdinals[3] = 4;
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(STRUCTOBJECTEXISTS, dObjectId), DBPARAMIO_INPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(STRUCTOBJECTEXISTS, bExists), DBPARAMIO_OUTPUT, sizeof(BOOL), DBTYPE_BOOL, 1);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(STRUCTOBJECTEXISTS, dClassId), DBPARAMIO_OUTPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(STRUCTOBJECTEXISTS, dScopeId), DBPARAMIO_OUTPUT, sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
if (!pSession)
{
hr = pDBInit->QueryInterface(IID_IDBCreateSession,
(void**) &pSession);
((COLEDBConnection*)pConn)->SetSessionObj(pSession);
}
if (pSession && !pCmd)
{
hr = pSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pCmd);
((COLEDBConnection*)pConn)->SetCommand(pCmd);
}
if (pCmd && !pICommandText)
{
hr = pCmd->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
if (SUCCEEDED(hr))
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
((COLEDBConnection*)pConn)->SetCommandText(SQL_POS_OBJECTEXISTS, pICommandText);
}
if (pICommandText && !pICommandWithParams)
{
hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams);
if (SUCCEEDED(hr))
hr = pICommandWithParams->SetParameterInfo(nParams, ParamOrdinals,ParamBindInfo);
((COLEDBConnection*)pConn)->SetCommandWithParams(SQL_POS_OBJECTEXISTS, pICommandWithParams);
}
if (pICommandWithParams && !pIAccessor)
{
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
((COLEDBConnection*)pConn)->SetIAccessor(SQL_POS_OBJECTEXISTS, pIAccessor);
}
if (pIAccessor && !hAccessor)
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding, sizeof(STRUCTOBJECTEXISTS),
&hAccessor,acDBBindStatus);
((COLEDBConnection*)pConn)->SetAccessor(SQL_POS_OBJECTEXISTS, hAccessor);
}
if (SUCCEEDED(hr))
{
Params.pData = &params;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (SUCCEEDED(hr))
{
if (dClassId)
*dClassId = CSQLExecute::GetInt64(&(params.dClassId));
if (dScopeId)
*dScopeId = CSQLExecute::GetInt64(&(params.dScopeId));
bExists = params.bExists;
}
else
hr = CSQLExecute::GetWMIError(pICommandText);
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::Execute
//
//***************************************************************************
HRESULT CSQLExecProcedure::Execute (CSQLConnection *pConn, LPCWSTR lpProcName, CWStringArray &arrValues,
IRowset **ppIRowset)
{
HRESULT hr = WBEM_S_NO_ERROR;
wchar_t wSQL[1024];
IDBCreateCommand *pCmd = ((COLEDBConnection *)pConn)->GetCommand();
swprintf(wSQL, L"exec %s ", lpProcName);
for (int i = 0; i < arrValues.Size(); i++)
{
if (i > 0)
wcscat(wSQL, L",");
wcscat(wSQL, L"\"");
wcscat(wSQL, arrValues.GetAt(i));
wcscat(wSQL, L"\"");
}
hr = CSQLExecute::ExecuteQuery(pCmd, wSQL, ppIRowset);
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::RenameSubscopes
//
//***************************************************************************
HRESULT CSQLExecProcedure::RenameSubscopes (CSQLConnection *pConn, LPWSTR lpOldPath, LPWSTR lpOldKey, LPWSTR lpNewPath, LPWSTR lpNewKey)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_RenameSubscopedObjs (?, ?, ?, ?) }";
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 4;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
typedef struct tagSPROCPARAMS
{
BSTR sOldPath;
BSTR sOldKey;
BSTR sNewPath;
BSTR sNewKey;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
sprocparams.sOldPath= SysAllocString(lpOldPath);
sprocparams.sOldKey= SysAllocString(lpOldKey);
sprocparams.sNewPath= SysAllocString(lpNewPath);
sprocparams.sNewKey= SysAllocString(lpNewKey);
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_BSTR", L"@OldPath", 4000, DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[0] = 1;
CSQLExecute::SetParamBindInfo(ParamBindInfo[1], L"DBTYPE_BSTR", L"@OldKey", 450, DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[1] = 2;
CSQLExecute::SetParamBindInfo(ParamBindInfo[2], L"DBTYPE_BSTR", L"@NewPath", 4000, DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[2] = 3;
CSQLExecute::SetParamBindInfo(ParamBindInfo[3], L"DBTYPE_BSTR", L"@NewKey", 450, DBPARAMFLAGS_ISINPUT, 11);
ParamOrdinals[3] = 4;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, sOldPath), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[1], 2, offsetof(SPROCPARAMS, sOldKey), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[2], 3, offsetof(SPROCPARAMS, sNewPath), DBPARAMIO_INPUT, 4000, DBTYPE_BSTR, 11);
CSQLExecute::SetBindingInfo(&acDBBinding[3], 4, offsetof(SPROCPARAMS, sNewKey), DBPARAMIO_INPUT, 450, DBTYPE_BSTR, 11);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding,
sizeof(SPROCPARAMS), &hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (FAILED(hr))
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::EnumerateSecuredChildren
//
//***************************************************************************
HRESULT CSQLExecProcedure::EnumerateSecuredChildren(CSQLConnection *pConn, CSchemaCache *pCache, SQL_ID dObjectId, SQL_ID dClassId, SQL_ID dScopeId,
SQLIDs &ObjIds, SQLIDs &ClassIds, SQLIDs &ScopeIds)
{
HRESULT hr = WBEM_S_NO_ERROR;
// If __Classes instance, we need to enumerate all instances of __ClassSecurity
// If this is a __ClassSecurity instance, we need to enumerate all instances
// of __ClassSecurity for all subclasses
// If this is a __ClassInstancesSecurity instance, we need to enumerate all
// instances of this class
// If this is a namespace (__ThisNamespace) or scope, we need all subscoped objects
SQL_ID dClassSecurityId = CLASSSECURITYID;
SQL_ID dClassesId = CLASSESID;
SQL_ID dClassInstSecurityId = CLASSINSTSECID;
SQL_ID dThisNamespaceId = THISNAMESPACEID;
DWORD dwSecPropID = 0;
hr = pCache->GetPropertyID(L"__SECURITY_DESCRIPTOR", 1, 0, REPDRVR_IGNORE_CIMTYPE, dwSecPropID);
if (dClassId == dClassesId)
{
IRowset *pIRowset = NULL;
DWORD dwNumRows = 0;
IMalloc *pMalloc = NULL;
CoGetMalloc(MEMCTX_TASK, &pMalloc);
CReleaseMe r (pMalloc);
// Enumerate all secured classes in this namespace.
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"select ObjectId, ClassId, ObjectScopeId from ObjectMap as o where ClassId = %I64d"
L" and exists (select * from ClassImages as c where c.ObjectId = o.ObjectId "
L" and c.PropertyId = %ld",
&pIRowset, &dwNumRows, dClassSecurityId, dwSecPropID);
if (SUCCEEDED(hr))
{
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, pMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
ObjIds.push_back(_wtoi64(vTemp.bstrVal));
hr = CSQLExecute::GetColumnValue(pIRowset, 2, pMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
ClassIds.push_back(_wtoi64(vTemp.bstrVal));
else
break;
hr = CSQLExecute::GetColumnValue(pIRowset, 3, pMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
ScopeIds.push_back(_wtoi64(vTemp.bstrVal));
else
break;
hr = pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
hr = CSQLExecute::GetColumnValue(pIRowset, 1, pMalloc, &pRow, vTemp);
}
}
pIRowset->Release();
pIRowset = NULL;
}
else if (dClassId == dClassSecurityId)
{
// All __ClassSecurity for subclasses of this class
// Get the class name
// Get the ID for the class name in this namespace
// Enumerate subclasses
// Format the name
// Generate the Object ID
return E_NOTIMPL;
}
else if (dClassId == dClassInstSecurityId)
{
// All instances of this class and subclasses.
// Get the class name
// Get the ID for the class name in this namespace
// Enumerate subclasses
// Enumerate all instances of each class
return E_NOTIMPL;
}
else
{
// Regular instance. Enumerate all objects
// scoped to this .
SQL_ID dThis = dObjectId;
if (dClassId == dThisNamespaceId)
dThis = dScopeId;
SQL_ID * pScopes = NULL;
int iNumScopes = 0;
hr = pCache->GetSubScopes(dThis, &pScopes, iNumScopes);
for (int i = 0; i < iNumScopes; i++)
{
IRowset *pIRowset = NULL;
DWORD dwNumRows = 0;
IMalloc *pMalloc = NULL;
CoGetMalloc(MEMCTX_TASK, &pMalloc);
CReleaseMe r (pMalloc);
// Enumerate all secured classes in this namespace.
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"select ObjectId, ClassId, ObjectScopeId from ObjectMap as o where ObjectScopeId = %I64d"
L" AND EXISTS (select * from ClassImages as c where c.ObjectId = c.ObjectId and c.PropertyId = %ld) ",
&pIRowset, &dwNumRows, pScopes[i], dwSecPropID);
if (SUCCEEDED(hr))
{
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hr = CSQLExecute::GetColumnValue(pIRowset, 1, pMalloc, &pRow, vTemp);
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
{
ObjIds.push_back(_wtoi64(vTemp.bstrVal));
hr = CSQLExecute::GetColumnValue(pIRowset, 2, pMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
ClassIds.push_back(_wtoi64(vTemp.bstrVal));
else
break;
hr = CSQLExecute::GetColumnValue(pIRowset, 3, pMalloc, &pRow, vTemp);
if (SUCCEEDED(hr))
ScopeIds.push_back(_wtoi64(vTemp.bstrVal));
else
break;
hr = pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
hr = CSQLExecute::GetColumnValue(pIRowset, 1, pMalloc, &pRow, vTemp);
}
}
pIRowset->Release();
pIRowset = NULL;
}
delete pScopes;
}
if (hr == WBEM_E_NOT_FOUND)
hr = WBEM_S_NO_ERROR;
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::EnumerateSubScopes
//
//***************************************************************************
HRESULT CSQLExecProcedure::EnumerateSubScopes (CSQLConnection *pConn, SQL_ID dScopeId)
{
HRESULT hr = WBEM_S_NO_ERROR;
const WCHAR *pszCmd = L"{call sp_EnumerateSubscopes (?) }";
IDBCreateCommand *pIDBCreateCommand = ((COLEDBConnection *)pConn)->GetCommand();
ICommandWithParameters *pICommandWithParams = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
HACCESSOR hAccessor = NULL;
const ULONG nParams = 1;
DBPARAMBINDINFO ParamBindInfo[nParams];
DBBINDING acDBBinding[nParams];
DBBINDSTATUS acDBBindStatus[nParams];
ULONG ParamOrdinals[nParams];
DBPARAMS Params;
LONG lRows = 0;
int i;
typedef struct tagSPROCPARAMS
{
DB_NUMERIC dScopeId;
} SPROCPARAMS;
SPROCPARAMS sprocparams;
CSQLExecute::SetDBNumeric(sprocparams.dScopeId, dScopeId);
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(IUnknown**) &pICommandText);
CReleaseMe r1 (pICommandText);
if (SUCCEEDED(hr))
{
pICommandText->SetCommandText(DBGUID_DBSQL, pszCmd);
CSQLExecute::SetParamBindInfo(ParamBindInfo[0], L"DBTYPE_NUMERIC", L"@ScopeId", sizeof(DB_NUMERIC), DBPARAMFLAGS_ISINPUT, 20);
ParamOrdinals[0] = 1;
if(SUCCEEDED(hr = pICommandText->QueryInterface(IID_ICommandWithParameters,(void**)&pICommandWithParams)))
{
CReleaseMe r2 (pICommandWithParams);
if(SUCCEEDED(hr = pICommandWithParams->SetParameterInfo(nParams,ParamOrdinals,ParamBindInfo)))
{
for(i = 0; i < nParams; i++)
CSQLExecute::ClearBindingInfo(&acDBBinding[i]);
CSQLExecute::SetBindingInfo(&acDBBinding[0], 1, offsetof(SPROCPARAMS, dScopeId), DBPARAMIO_INPUT,
sizeof(DB_NUMERIC), DBTYPE_NUMERIC, 20);
hr = pICommandWithParams->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
CReleaseMe r3 (pIAccessor);
if (SUCCEEDED(hr))
{
hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,nParams, acDBBinding,
sizeof(SPROCPARAMS), &hAccessor,acDBBindStatus);
if (SUCCEEDED(hr))
{
Params.pData = &sprocparams;
Params.cParamSets = 1;
Params.hAccessor = hAccessor;
hr = pICommandText->Execute(NULL, IID_IRowset, &Params, &lRows, (IUnknown **) &pIRowset);
CReleaseMe r4 (pIRowset);
if (FAILED(hr))
hr = CSQLExecute::GetWMIError(pICommandText);
pIAccessor->ReleaseAccessor(hAccessor, NULL);
}
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertScopeMap
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertScopeMap (CSQLConnection *pConn, SQL_ID dScopeId, LPCWSTR lpScopePath, SQL_ID dParentId)
{
return E_NOTIMPL;
}
//***************************************************************************
//
// CSQLExecProcedure::GetSecurityDescriptor
//
//***************************************************************************
HRESULT CSQLExecProcedure::GetSecurityDescriptor(CSQLConnection *pConn, SQL_ID dObjectId,
PNTSECURITY_DESCRIPTOR * ppSD, DWORD &dwBuffLen,
DWORD dwFlags)
{
HRESULT hr = WBEM_E_NOT_FOUND;
// If this is a class , get the security for __ClassSecurity (WMIDB_SECURITY_FLAG_CLASS)
// or __Instances container (WMIDB_SECURITY_FLAG_INSTANCE)
// If this is a namespace, get the security for __ThisNamespace
// Otherwise, get it off the object itself.
*ppSD = NULL;
IRowset *pIRowset = NULL;
DWORD dwNumRows = 0;
IMalloc *pMalloc = NULL;
CoGetMalloc(MEMCTX_TASK, &pMalloc);
CReleaseMe r (pMalloc);
HRESULT hres = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"exec sp_GetSecurityInfo %I64d, %ld",
&pIRowset, &dwNumRows, dObjectId, dwFlags);
if (SUCCEEDED(hres) && hres != WBEM_S_NO_MORE_DATA)
{
// Get the results and load the cache.
HROW *pRow = NULL;
VARIANT vTemp;
CClearMe c (&vTemp);
hres = CSQLExecute::GetColumnValue(pIRowset, 1, pMalloc, &pRow, vTemp);
if (SUCCEEDED(hres) && hres != WBEM_S_NO_MORE_DATA)
{
PNTSECURITY_DESCRIPTOR pSecDescr = NULL;
VariantClear(&vTemp);
BYTE *pBuffer = NULL;
bool bThisObj = true;
// Get the image data for this security descriptor.
hres = CSQLExecute::ReadImageValue(pIRowset, 1, &pRow, &pBuffer, dwBuffLen);
if (SUCCEEDED(hres) && pBuffer != NULL)
{
pSecDescr = pBuffer;
if (pSecDescr != NULL)
{
if (IsValidSecurityDescriptor(pSecDescr))
{
hr = WBEM_S_NO_ERROR;
*ppSD = pSecDescr;
}
else
CWin32DefaultArena::WbemMemFree(pSecDescr); // FIXME: This breakpoints...
}
VariantClear(&vTemp);
// DON'T DELETE pBuffer, since this is our copy.
}
hres = pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
}
pIRowset->Release();
pIRowset = NULL;
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::InsertUncommittedEvent
//
//***************************************************************************
HRESULT CSQLExecProcedure::InsertUncommittedEvent (CSQLConnection *pConn, LPCWSTR lpGUID, LPWSTR lpNamespace,
LPWSTR lpClassName, IWbemClassObject *pOldObj,
IWbemClassObject *pNewObj, CSchemaCache *pCache)
{
HRESULT hr = WBEM_S_NO_ERROR;
static int iNumProps = 5;
InsertPropValues *pVals = new InsertPropValues[iNumProps];
if (!pVals)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe <InsertPropValues> d (pVals);
LPWSTR lpObjectKey = NULL, lpPath = NULL;
SQL_ID dScopeId = 1;
SQL_ID dObjectId = 0;
SQL_ID dKeyhole = 0;
static SQL_ID dClassId = 0;
static DWORD dwPropId1 = 0, dwPropId2 = 0, dwPropId3 = 0, dwPropId4 = 0, dwPropId5 = 0, dwPropId6 = 0, dwPropId7 = 0;
if (!dwPropId1)
{
hr = pCache->GetClassID(L"__UncommittedEvent", 1, dClassId);
if (SUCCEEDED(hr))
{
hr = pCache->GetPropertyID(L"EventID", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId1);
hr = pCache->GetPropertyID(L"TransactionGUID", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId2);
hr = pCache->GetPropertyID(L"NamespaceName", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId3);
hr = pCache->GetPropertyID(L"ClassName", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId4);
hr = pCache->GetPropertyID(L"OldObject", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId5);
hr = pCache->GetPropertyID(L"NewObject", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId6);
hr = pCache->GetPropertyID(L"Transacted", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId7);
}
}
if (FAILED(hr))
return hr;
hr = GetNextKeyhole(pConn, dwPropId1, dKeyhole);
if (SUCCEEDED(hr))
{
LPWSTR lpKey = new wchar_t [40];
lpObjectKey = new wchar_t [100];
lpPath = new wchar_t [100];
CDeleteMe <wchar_t> d2 (lpKey), d3 (lpObjectKey), d4 (lpPath);
if (!lpKey || !lpObjectKey || !lpPath)
return WBEM_E_OUT_OF_MEMORY;
swprintf(lpKey, L"%ld", dKeyhole);
swprintf(lpObjectKey, L"%ld?__UncommittedEvent", dKeyhole);
swprintf(lpPath, L"__UncommittedEvent=%ld", dKeyhole);
pVals[0].iPropID = dwPropId1;
pVals[0].bIndexed = TRUE;
pVals[0].iStorageType = WMIDB_STORAGE_NUMERIC;
pVals[0].dClassId = dClassId;
pVals[0].pValue = Macro_CloneLPWSTR(lpKey);
pVals[1].iPropID = dwPropId2;
pVals[1].bIndexed = TRUE;
pVals[1].iStorageType = WMIDB_STORAGE_STRING;
pVals[1].dClassId = dClassId;
pVals[1].pValue = Macro_CloneLPWSTR(lpGUID);
pVals[2].iPropID = dwPropId3;
pVals[2].iStorageType = WMIDB_STORAGE_STRING;
pVals[2].dClassId = dClassId;
pVals[2].pValue = Macro_CloneLPWSTR(lpClassName);
pVals[3].iPropID = dwPropId4;
pVals[3].iStorageType = WMIDB_STORAGE_STRING;
pVals[3].dClassId = dClassId;
pVals[3].pValue = Macro_CloneLPWSTR(lpNamespace);
pVals[4].iPropID = dwPropId6;
pVals[4].iStorageType = WMIDB_STORAGE_NUMERIC;
pVals[4].dClassId = dClassId;
pVals[4].pValue = new wchar_t [2];
if (!pVals[4].pValue)
return WBEM_E_OUT_OF_MEMORY;
wcscpy(pVals[4].pValue, L"1");
hr = InsertPropertyBatch (pConn, lpObjectKey, lpPath, lpClassName,
dClassId, dScopeId, 0, pVals, iNumProps, dObjectId);
if (SUCCEEDED(hr))
{
if (pOldObj)
{
_IWmiObject *pInt = NULL;
hr = pOldObj->QueryInterface(IID__IWmiObject, (void **)&pInt);
if (SUCCEEDED(hr))
{
DWORD dwLen = 0;
pInt->GetObjectMemory(NULL, 0, &dwLen);
BYTE *pBuff = new BYTE [dwLen];
if (pBuff)
{
CDeleteMe <BYTE> d (pBuff);
DWORD dwLen1;
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
if (SUCCEEDED(hr))
{
hr = CSQLExecProcedure::InsertBlobData(pConn, dClassId, dObjectId,
dwPropId4, pBuff, 0, dwLen);
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
pInt->Release();
}
}
if (pNewObj)
{
_IWmiObject *pInt = NULL;
hr = pNewObj->QueryInterface(IID__IWmiObject, (void **)&pInt);
if (SUCCEEDED(hr))
{
DWORD dwLen = 0;
pInt->GetObjectMemory(NULL, 0, &dwLen);
BYTE *pBuff = new BYTE [dwLen];
if (pBuff)
{
CDeleteMe <BYTE> d (pBuff);
DWORD dwLen1;
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
if (SUCCEEDED(hr))
{
hr = CSQLExecProcedure::InsertBlobData(pConn, dClassId, dObjectId,
dwPropId4, pBuff, 0, dwLen);
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
pInt->Release();
}
}
}
}
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::DeleteUncommittedEvents
//
//***************************************************************************
HRESULT CSQLExecProcedure::DeleteUncommittedEvents (CSQLConnection *pConn, LPCWSTR lpGUID,
CSchemaCache *pCache, CObjectCache *pObjCache)
{
HRESULT hr = WBEM_S_NO_ERROR;
// FIXME: Bind and optimize later.
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(), L"exec sp_DeleteUncommittedEvents '%s'", NULL, NULL, lpGUID);
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::CommitEvents
//
//***************************************************************************
HRESULT CSQLExecProcedure::CommitEvents(CSQLConnection *pConn,_IWmiCoreServices *pESS,
LPCWSTR lpRoot, LPCWSTR lpGUID, CSchemaCache *pCache, CObjectCache *pObjCache)
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT vValue;
VariantInit(&vValue);
CClearMe c (&vValue);
IRowset *pRowset = NULL;
DWORD dwNumRows = 0;
IMalloc *pMalloc = NULL;
CoGetMalloc(MEMCTX_TASK, &pMalloc);
CReleaseMe r (pMalloc);
SQL_ID dObjectId;
_IWmiObject *pOldObj, *pNewObj;
_IWmiObject **pObjs;
DWORD dwNumObjs;
_bstr_t sNamespace, sClassName;
LPWSTR lpNewNs = NULL;
HROW *pRow = NULL;
long lType;
hr = CSQLExecute::ExecuteQuery(((COLEDBConnection *)pConn)->GetCommand(),
L"exec sp_GetUncommittedEvents '%s'", &pRowset, &dwNumRows, lpGUID);
if (SUCCEEDED(hr))
{
hr = CSQLExecute::GetColumnValue(pRowset, 1, pMalloc, &pRow, vValue);
while (hr == WBEM_S_NO_ERROR)
{
BYTE *pBuff = NULL;
DWORD dwLen = 0;
dObjectId = _wtoi64(vValue.bstrVal);
hr = CSQLExecute::GetColumnValue(pRowset, 2, pMalloc, &pRow, vValue);
sNamespace = vValue.bstrVal;
hr = CSQLExecute::GetColumnValue(pRowset, 3, pMalloc, &pRow, vValue);
sClassName = vValue.bstrVal;
hr = CSQLExecute::ReadImageValue(pRowset, 4, &pRow, &pBuff, dwLen);
if (SUCCEEDED(hr) && dwLen)
hr = ConvertBlobToObject(NULL, pBuff, dwLen, &pOldObj);
else
pOldObj = NULL;
delete pBuff;
hr = CSQLExecute::ReadImageValue(pRowset, 5, &pRow, &pBuff, dwLen);
if (SUCCEEDED(hr) && dwLen)
hr = ConvertBlobToObject(NULL, pBuff, dwLen, &pNewObj);
else
pNewObj = NULL;
delete pBuff;
lpNewNs = new wchar_t [wcslen(sNamespace) + 50];
if (lpNewNs)
{
swprintf(lpNewNs, L"\\\\.\\%s\\%s", lpRoot, (LPCWSTR)sNamespace);
}
CDeleteMe <wchar_t> d4 (lpNewNs);
// Determine what type of event this is:
// Namespace | Class | Instance
// Creation | Modification | Deletion
// =====================================
if (!pNewObj && pOldObj)
{
pObjs = new _IWmiObject * [dwNumObjs];
pObjs[0] = pOldObj;
LPWSTR lpGenus = GetPropertyVal(L"__Genus", pNewObj);
CDeleteMe <wchar_t> d (lpGenus);
if (!wcscmp(lpGenus, L"1"))
lType = WBEM_EVENTTYPE_ClassDeletion;
else
{
if (IsDerivedFrom(pOldObj, L"__Namespace"))
lType = WBEM_EVENTTYPE_NamespaceDeletion;
else
lType = WBEM_EVENTTYPE_InstanceDeletion;
}
}
else if (!pOldObj && pNewObj)
{
pObjs = new _IWmiObject *[dwNumObjs];
if (pObjs)
{
pObjs[0] = pNewObj;
LPWSTR lpGenus = GetPropertyVal(L"__Genus", pNewObj);
CDeleteMe <wchar_t> d (lpGenus);
if (!wcscmp(lpGenus, L"1"))
lType = WBEM_EVENTTYPE_ClassCreation;
else
{
if (IsDerivedFrom(pOldObj, L"__Namespace"))
lType = WBEM_EVENTTYPE_NamespaceCreation;
else
lType = WBEM_EVENTTYPE_InstanceCreation;
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else
{
dwNumObjs = 2;
pObjs = new _IWmiObject *[dwNumObjs];
if (pObjs)
{
pObjs[0] = pOldObj;
pObjs[1] = pNewObj;
LPWSTR lpGenus = GetPropertyVal(L"__Genus", pNewObj);
CDeleteMe <wchar_t> d (lpGenus);
if (!wcscmp(lpGenus, L"1"))
lType = WBEM_EVENTTYPE_ClassModification;
else
{
if (IsDerivedFrom(pOldObj, L"__Namespace"))
lType = WBEM_EVENTTYPE_NamespaceModification;
else
lType = WBEM_EVENTTYPE_InstanceModification;
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
// Deliver the event...
// ====================
pESS->DeliverIntrinsicEvent(lpNewNs, lType, NULL,
sClassName, lpGUID, dwNumObjs, pObjs);
delete pObjs;
if (pOldObj)
pOldObj->Release();
if (pNewObj)
pNewObj->Release();
pObjCache->DeleteObject(dObjectId);
if (pRow)
pRowset->ReleaseRows(1, pRow, NULL, NULL, NULL);
delete pRow;
pRow = NULL;
hr = CSQLExecute::GetColumnValue(pRowset, 1, pMalloc, &pRow, vValue);
}
}
// Remove all events for this GUID.
// FIXME: Do this incrementally in the future.
// The problem is, we would have to reissue the query
// after doing this, which isn't terribly efficient.
if (SUCCEEDED(hr))
hr = DeleteUncommittedEvents(pConn, lpGUID, pCache, pObjCache);
return hr;
}
//***************************************************************************
//
// CSQLExecProcedure::UpdateClassBlob
//
//***************************************************************************
HRESULT CSQLExecProcedure::UpdateClassBlob (CSQLConnection *pConn, SQL_ID dClassId, _IWmiObject *pObj)
{
HRESULT hr = 0;
BYTE buff[128];
DWORD dwLen = 0;
hr = ((_IWmiObject *)pObj)->Unmerge(0, 128, &dwLen, &buff);
if (dwLen > 0)
{
BYTE *pBuff = new BYTE [dwLen];
if (pBuff)
{
CDeleteMe <BYTE> r2 (pBuff);
DWORD dwLen1;
hr = ((_IWmiObject *)pObj)->Unmerge(0, dwLen, &dwLen1, pBuff);
if (SUCCEEDED(hr))
{
wchar_t wBuff[256];
swprintf(wBuff, L"select ClassBlob from ClassMap "
L" where ClassId = %I64d", dClassId);
if (SUCCEEDED(hr))
{
hr = CSQLExecute::WriteImageValue
(((COLEDBConnection *)pConn)->GetCommand(), wBuff, 1, pBuff, dwLen);
}
}
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
return hr;
}