|
|
//***************************************************************************
//
// (c) 1999-2001 by Microsoft Corp. All Rights Reserved.
//
// sqlit.cpp
//
// cvadai 19-Mar-99 Created as prototype for Quasar.
//
//***************************************************************************
#define _SQLIT_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
#define DBINITCONSTANTS // Initialize OLE constants...
#define INITGUID // ...once in each app.
#define _WIN32_DCOM
#include "precomp.h"
#include <std.h>
#include <sqlutils.h>
#include <repdrvr.h>
#include <sqlit.h>
#include <wbemint.h>
//***************************************************************************
//
// CWmiDbIterator::CWmiDbIterator
//
//***************************************************************************
CWmiDbIterator::CWmiDbIterator() { m_pStatus = NULL; m_pRowset = NULL; m_pSession = NULL; m_pIMalloc = NULL; m_pConn = NULL; m_uRefCount = 0; }
//***************************************************************************
//
// CWmiDbIterator::~CWmiDbIterator
//
//***************************************************************************
CWmiDbIterator::~CWmiDbIterator() { Cancel(0); if (m_pSession) m_pSession->Release(); if (m_pIMalloc) m_pIMalloc->Release(); }
//***************************************************************************
//
// CWmiDbIterator::QueryInterface
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiDbIterator::QueryInterface (REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) { *ppvObject = 0;
if (IID_IUnknown==riid || IID_IWmiDbIterator==riid ) { *ppvObject = (IWmiDbIterator *)this; AddRef(); return S_OK; }
return E_NOINTERFACE; }
//***************************************************************************
//
// CWmiDbIterator::AddRef
//
//***************************************************************************
ULONG STDMETHODCALLTYPE CWmiDbIterator::AddRef() { InterlockedIncrement((LONG *) &m_uRefCount); return m_uRefCount; }
//***************************************************************************
//
// CWmiDbIterator::Release
//
//***************************************************************************
ULONG STDMETHODCALLTYPE CWmiDbIterator::Release() { ULONG uNewCount = InterlockedDecrement((LONG *) &m_uRefCount); if (0 != uNewCount) return uNewCount; delete this; return WBEM_S_NO_ERROR; } //***************************************************************************
//
// CWmiDbIterator::Cancel
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiDbIterator::Cancel( /* [in] */ DWORD dwFlags) { HRESULT hr = WBEM_S_NO_ERROR;
hr = CSQLExecute::CancelQuery(m_pStatus);
if (m_pStatus) m_pStatus->Release(); m_pStatus = NULL;
if (m_pConn) { ((CWmiDbController *)m_pSession->m_pController)->ConnCache.ReleaseConnection(m_pConn, hr); m_pConn = NULL; }
if (m_pRowset) m_pRowset->Release(); m_pRowset = NULL;
return hr; }
//***************************************************************************
//
// CWmiDbIterator::NextBatch
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiDbIterator::NextBatch( /* [in] */ DWORD dwNumRequested, /* [in] */ DWORD dwTimeOutSeconds, /* [in] */ DWORD dwFlags, /* [in] */ DWORD dwRequestedHandleType, /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwNumReturned, /* [iid_is][length_is][size_is][out] */ LPVOID __RPC_FAR *ppObjects) {
HRESULT hr = WBEM_S_NO_ERROR, hrRet = WBEM_S_NO_ERROR; bool bImmediate = !(dwRequestedHandleType & WMIDB_HANDLE_TYPE_SUBSCOPED);
if (!m_pSession || !(m_pSession->m_pController) || ((CWmiDbController *)m_pSession->m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN) return WBEM_E_SHUTTING_DOWN;
if (!dwNumRequested || !ppObjects) return WBEM_E_INVALID_PARAMETER;
if (dwRequestedHandleType == WMIDB_HANDLE_TYPE_INVALID && riid == IID_IWmiDbHandle) return WBEM_E_INVALID_PARAMETER;
// FIXME: We need to create a readahead cache.
if (dwFlags & WMIDB_FLAG_LOOKAHEAD || (riid != IID_IWmiDbHandle && riid != IID_IWbemClassObject && riid != IID__IWmiObject)) /// UuidCompare(pIIDRequestedInterface, &IID_IWmiDbHandle, NULL) ||
// UuidCompare(pIIDRequestedInterface, &IID_IWbemClassObject, NULL))
return WBEM_E_NOT_SUPPORTED;
if (pdwNumReturned) *pdwNumReturned = 0;
if (!m_pStatus && !m_pRowset) return WBEM_S_NO_MORE_DATA;
// For each ObjectId, do we instantiate a new handle,
// and increment a background ref count on the object itself?
// How do we keep track of the handles that are in use??
try {
HROW *pRow = NULL; VARIANT vTemp; VariantInit(&vTemp); int iNumRetrieved = 0; IRowset *pIRowset = NULL;
if (m_pStatus) { hr = CSQLExecute::IsDataReady(m_pStatus); // TO DO: Wait if we are pending. Fail for now.
if (SUCCEEDED(hr)) { hr = m_pStatus->QueryInterface(IID_IRowset, (void **)&pIRowset); } } else pIRowset = m_pRowset;
if (SUCCEEDED(hr) && pIRowset) { // TO DO: Take the timeout value into consideration!!!
hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp); while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA && iNumRetrieved < dwNumRequested) {
if (!m_pSession || !(m_pSession->m_pController) || ((CWmiDbController *)m_pSession->m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN) { hrRet = WBEM_E_SHUTTING_DOWN; break; }
// At this point, we need to check the cache
// to make sure we don't already have one of these,
// and that its not locked.
SQL_ID dID = 0; if (vTemp.vt == VT_BSTR) dID = _wtoi64(vTemp.bstrVal); else if (vTemp.vt == VT_I4) dID = vTemp.lVal;
SQL_ID dClassID = 0, dScopeID = 0; DWORD dwLockType = 0;
VariantClear(&vTemp); hr = CSQLExecute::GetColumnValue(pIRowset, 2, m_pIMalloc, &pRow, vTemp); if (vTemp.vt == VT_BSTR) dClassID = _wtoi64(vTemp.bstrVal); else if (vTemp.vt == VT_I4) dClassID = vTemp.lVal;
VariantClear(&vTemp); hr = CSQLExecute::GetColumnValue(pIRowset, 3, m_pIMalloc, &pRow, vTemp);
if (vTemp.vt == VT_BSTR) dScopeID = _wtoi64(vTemp.bstrVal); else if (vTemp.vt == VT_I4) dScopeID = vTemp.lVal;
VariantClear(&vTemp);
//hr = ((CWmiDbSession *)m_pSession)->VerifyObjectSecurity(NULL, dID, dClassID, dScopeID, 0, WBEM_ENABLE);
if (SUCCEEDED(hr)) { CWmiDbHandle *pTemp = new CWmiDbHandle; if (pTemp) { DWORD dwVersion = 0; // Obtain a lock for this object
// =============================
pTemp->m_pSession = m_pSession;
hr = ((CWmiDbController *)m_pSession->m_pController)->LockCache.AddLock(bImmediate, dID, dwRequestedHandleType, pTemp, dScopeID, dClassID, &((CWmiDbController *)m_pSession->m_pController)->SchemaCache, false, 0, 0, &dwVersion);
if (FAILED(hr)) { delete pTemp; // If they failed to get a handle, what do we do?
// Ignore it and continue, I guess.
hrRet = WBEM_S_PARTIAL_RESULTS; ppObjects[iNumRetrieved] = NULL; } else { ((CWmiDbController *)m_pSession->m_pController)->AddHandle(); pTemp->AddRef(); pTemp->m_dwVersion = dwVersion; pTemp->m_dwHandleType = dwRequestedHandleType; pTemp->m_dClassId = dClassID; pTemp->m_dObjectId = dID; if (dwFlags & WBEM_FLAG_USE_SECURITY_DESCRIPTOR) pTemp->m_bSecDesc = TRUE;
if (pTemp->m_dClassId == MAPPEDNSCLASSID) pTemp->m_bDefault = FALSE;
pTemp->m_dScopeId = dScopeID;
if (riid == IID_IWmiDbHandle) { ppObjects[iNumRetrieved] = pTemp; iNumRetrieved++; } else if (riid == IID_IWbemClassObject || riid == IID__IWmiObject) { IWbemClassObject *pTemp2 = NULL; hr = pTemp->QueryInterface(IID_IWbemClassObject, (void **)&pTemp2); ppObjects[iNumRetrieved] = pTemp2; if (FAILED(hr)) hrRet = WBEM_S_PARTIAL_RESULTS; else iNumRetrieved++; pTemp->Release(); } } } else { // *pQueryResult = NULL; // What do we do here? Cancel, I assume.
hrRet = WBEM_E_OUT_OF_MEMORY; break; } } else hrRet = WBEM_S_PARTIAL_RESULTS;
if (m_pSession && ((CWmiDbSession *)m_pSession)->m_pController) ((CWmiDbController *)m_pSession->m_pController)->IncrementHitCount(false);
VariantClear(&vTemp);
hr = pIRowset->ReleaseRows(1, pRow, NULL, NULL, NULL); delete pRow; pRow = NULL; if (iNumRetrieved == dwNumRequested) break; hr = CSQLExecute::GetColumnValue(pIRowset, 1, m_pIMalloc, &pRow, vTemp); } }
if (pdwNumReturned) *pdwNumReturned = iNumRetrieved;
// Null out m_pStatus if there are no more results!!!
if (hr == WBEM_S_NO_MORE_DATA) { hrRet = WBEM_S_NO_MORE_DATA; Cancel(0); } } catch (...) { hrRet = WBEM_E_CRITICAL_ERROR; }
return hrRet; }
|