281 lines
8.9 KiB
C++
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;
|
|
} |