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

281 lines
8.9 KiB
C++

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// interface implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Opens and returns a rowset that includes all rows from a single base table
//
// HRESULT
// S_OK The method succeeded
// E_INVALIDARG pTableID was NULL
// E_FAIL Provider-specific error
// DB_E_NOTABLE Specified table does not exist in current Data Data Source object
// E_OUTOFMEMORY Out of memory
// E_NOINTERFACE The requested interface was not available
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIOpenRowset::OpenRowset( IUnknown* pUnkOuter, // IN Controlling unknown, if any
DBID* pTableID, // IN table to open
DBID* pIndexID, // IN DBID of the index
REFIID riid, // IN interface to return
ULONG cPropertySets, // IN count of properties
DBPROPSET rgPropertySets[], // INOUT array of property values
IUnknown** ppRowset // OUT where to return interface
)
{
CRowset* pRowset = NULL;
HRESULT hr = S_OK;
HRESULT hrProp = S_OK ;
BOOL bRowRequested = FALSE;
CRow* pRow = NULL;
ULONG cErrors = 0;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
assert( m_pObj );
assert( m_pObj->m_pUtilProp );
//=====================================================================
// NULL out-params in case of error
//=====================================================================
if( ppRowset )
{
*ppRowset = NULL;
}
// Seriliaze the object
CAutoBlock cab(m_pObj->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//=====================================================================
// Check Arguments
//=====================================================================
if ( !pTableID && !pIndexID )
{
hr = E_INVALIDARG;
// return g_pCError->PostHResult(E_INVALIDARG,&IID_IOpenRowset);
}
else
if ( riid == IID_NULL)
{
hr = E_NOINTERFACE;
// return g_pCError->PostHResult(E_NOINTERFACE,&IID_IOpenRowset) ;
}
else
//==========================================================
// We only accept NULL for pIndexID at this present time
//==========================================================
if( pIndexID )
{
hr = DB_E_NOINDEX;
// return g_pCError->PostHResult(DB_E_NOINDEX,&IID_IOpenRowset) ;
}
else
//===================================================================================
// We do not allow the riid to be anything other than IID_IUnknown for aggregation
//===================================================================================
if ( (pUnkOuter) && (riid != IID_IUnknown) )
{
hr = DB_E_NOAGGREGATION;
// return g_pCError->PostHResult(DB_E_NOAGGREGATION,&IID_IOpenRowset) ;
}
else
//==============================================
// validate the property sets to be set
//==============================================
if( SUCCEEDED(hr = m_pObj->m_pUtilProp->SetPropertiesArgChk(cPropertySets, rgPropertySets,TRUE)) )
{
//=================================================================
// If the eKind is not known to use, basically it means we have no
// table identifier
//=================================================================
if ( (!pTableID ) || ( pTableID->eKind != DBKIND_NAME ) || ( (pTableID->eKind == DBKIND_NAME) && (!(pTableID->uName.pwszName)) ) ||
( wcslen(pTableID->uName.pwszName) == 0 ) || ( wcslen(pTableID->uName.pwszName) > _MAX_FNAME ) )
{
hr = DB_E_NOTABLE ;
}
else
{
if( riid == IID_IRow || riid == IID_IRowChange ||
GetIRowProp(cPropertySets,rgPropertySets) == TRUE)
{
bRowRequested = TRUE;
}
// If rowset is to be created then create a new rowset
if( bRowRequested == FALSE)
{
//===============================================================================
// open and initialize a rowset\cursor object
//===============================================================================
// pRowset = new CRowset(pUnkOuter,NO_QUALIFIERS,(LPWSTR)(pTableID->uName.pwszName),m_pObj);
try
{
pRowset = new CRowset(pUnkOuter,m_pObj);
}
catch(...)
{
SAFE_DELETE_PTR(pRowset);
throw;;
}
if (!pRowset)
{
hr = E_OUTOFMEMORY ;
}
else
{
//===========================================================================
// if properties failed or ppRowset NULL
//===========================================================================
hr = pRowset->InitRowset(cPropertySets, rgPropertySets,(LPWSTR)(pTableID->uName.pwszName));
if( (SUCCEEDED(hr)) )
{
if(hr != S_OK)
{
cErrors++;
}
//=======================================================================
// get requested interface pointer on rowset\cursor
//=======================================================================
if(ppRowset != NULL)
{
hr = pRowset->QueryInterface( riid, (void **) ppRowset );
if (SUCCEEDED( hr ))
{
//===================================================================
//Assign creator pointer. Used for IRowsetInfo::GetSpecification
//===================================================================
// m_pObj->m_fRowsetCreated = TRUE;
}
}
else
{
SAFE_DELETE_PTR(pRowset);
hr = cErrors > 0 ? DB_S_ERRORSOCCURRED : S_OK;
}
}
} // else for failure of allocation of pRowset
}
// Create a row
else
{
CURLParser urlParser;
VARIANT varNameSpace;
BSTR strClassName,strObject;
strObject = Wmioledb_SysAllocString(pTableID->uName.pwszName);
VariantInit(&varNameSpace);
// Get the namespace of the datasource
m_pObj->GetDataSrcProperty(DBPROP_INIT_DATASOURCE,varNameSpace);
hr = urlParser.SetURL(strObject);
SAFE_FREE_SYSSTRING(strObject);
if(SUCCEEDED(hr))
{
// urlParser.SetNameSpace(varNameSpace.bstrVal);
urlParser.GetClassName(strClassName);
urlParser.GetPath(strObject);
try
{
// Create a new row on the instance
pRow = new CRow(pUnkOuter,m_pObj);
}
catch(...)
{
SAFE_DELETE_PTR(pRow);
throw;
}
if(pRow == NULL)
{
hr = E_OUTOFMEMORY;
}
else
{
// call this function to initialize the row
hr = pRow->InitRow(strObject,strClassName);
if(hr == S_OK)
{
// QI for the required interface
hr = pRow->QueryInterface(riid,(void **)ppRowset);
}
}
}
// Freeing the variables
VariantClear(&varNameSpace);
SysFreeString(strClassName);
SysFreeString(strObject);
} // end of creating row
} // if valid table name
}
if( FAILED(hr ) )
{
SAFE_DELETE_PTR( pRowset );
SAFE_DELETE_PTR( pRow );
}
if(hr == S_OK && cErrors > 0)
{
hr = DB_S_ERRORSOCCURRED;
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IOpenRowset);
CATCH_BLOCK_HRESULT(hr,L"IOpenRowset::OpenRowset");
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to get a DBPROP_IRow property
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CImpIOpenRowset::GetIRowProp(ULONG cPropertySets, // IN count of properties
DBPROPSET rgPropertySets[])
{
BOOL bRet = FALSE;
for( ULONG lIndex = 0 ; lIndex < cPropertySets ; lIndex++)
{
if(rgPropertySets[lIndex].guidPropertySet == DBPROPSET_ROWSET)
{
for ( ULONG nPropIndex = 0 ; nPropIndex < rgPropertySets[lIndex].cProperties ; nPropIndex++ )
{
if(rgPropertySets[lIndex].rgProperties[nPropIndex].dwPropertyID == DBPROP_IRow &&
rgPropertySets[lIndex].rgProperties[nPropIndex].vValue.boolVal == VARIANT_TRUE)
{
bRet = TRUE;
} // if DBPROP_IRow is true;
}// for loop
} // if propertyset is DBPROPSET_ROWSET
} // outer for loop
return bRet;
}