683 lines
23 KiB
C++
683 lines
23 KiB
C++
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Microsoft WMI OLE DB Provider
|
||
|
//
|
||
|
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
// Module : CMDPARAM.CPP - ICommandWithParameters interface implementation
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
#include "headers.h"
|
||
|
#include "command.h"
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Increments a reference count for the object.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP_(ULONG) CImpICommandWithParameters::AddRef(void)
|
||
|
{
|
||
|
DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
|
||
|
return m_pcmd->AddRef();
|
||
|
}
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Decrement the object's reference count and deletes the object when the new reference count is zero.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP_(ULONG) CImpICommandWithParameters::Release(void)
|
||
|
{
|
||
|
DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef));
|
||
|
DEBUGCODE(if( lRef < 0 ){
|
||
|
ASSERT("Reference count on Object went below 0!")
|
||
|
});
|
||
|
|
||
|
return m_pcmd->GetOuterUnknown()->Release();
|
||
|
}
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Returns a pointer to a specified interface. Callers use QueryInterface to determine which interfaces the
|
||
|
// called object supports.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CImpICommandWithParameters::QueryInterface( REFIID riid, LPVOID * ppv )
|
||
|
{
|
||
|
return m_pcmd->QueryInterface(riid, ppv);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Get a list of the command's parameters, their names, and their required types.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CImpICommandWithParameters::GetParameterInfo( DB_UPARAMS* pcParams, DBPARAMINFO** prgParamInfo, OLECHAR** ppNamesBuffer )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
CSetStructuredExceptionHandler seh;
|
||
|
|
||
|
TRY_BLOCK;
|
||
|
|
||
|
//=========================================================
|
||
|
// Serialize access
|
||
|
//=========================================================
|
||
|
CAutoBlock cab(m_pcmd->GetCriticalSection());
|
||
|
|
||
|
//=========================================================
|
||
|
// Clear previous Error Object for this thread
|
||
|
//=========================================================
|
||
|
g_pCError->ClearErrorInfo();
|
||
|
|
||
|
//=========================================================
|
||
|
// Initialize buffers
|
||
|
//=========================================================
|
||
|
if ( pcParams )
|
||
|
{
|
||
|
*pcParams = 0;
|
||
|
}
|
||
|
if ( prgParamInfo )
|
||
|
{
|
||
|
*prgParamInfo = NULL;
|
||
|
}
|
||
|
if ( ppNamesBuffer )
|
||
|
{
|
||
|
*ppNamesBuffer = NULL;
|
||
|
}
|
||
|
|
||
|
//=========================================================
|
||
|
// Validate Agruments
|
||
|
//=========================================================
|
||
|
if ( (pcParams == NULL) || (prgParamInfo == NULL) )
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
else
|
||
|
//=========================================================
|
||
|
// If the consumer has not supplied parameter information.
|
||
|
//=========================================================
|
||
|
if ( m_pcmd->m_pQuery->GetParamCount() == 0 )
|
||
|
{
|
||
|
|
||
|
//=====================================================
|
||
|
// Command Object must be in prepared state
|
||
|
//=====================================================
|
||
|
if ( !(m_pcmd->m_pQuery->GetStatus() & CMD_READY) )
|
||
|
{
|
||
|
hr = DB_E_NOTPREPARED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = m_pcmd->GetParameterInfo(pcParams, prgParamInfo, ppNamesBuffer, &IID_ICommandWithParameters);
|
||
|
}
|
||
|
|
||
|
hr = hr == S_OK ? hr : g_pCError->PostHResult(hr,&IID_ICommandWithParameters);
|
||
|
|
||
|
CATCH_BLOCK_HRESULT(hr,L"ICommandWithParameters::GetParameterInfo");
|
||
|
return hr;
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Map parameter names to parameter ordinals
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CImpICommandWithParameters::MapParameterNames( DB_UPARAMS cParamNames, const OLECHAR* rgParamNames[], DB_LPARAMS rgParamOrdinals[] )
|
||
|
{
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
CSetStructuredExceptionHandler seh;
|
||
|
|
||
|
TRY_BLOCK;
|
||
|
|
||
|
//=========================================================
|
||
|
// Serialize access
|
||
|
//=========================================================
|
||
|
CAutoBlock cab(m_pcmd->GetCriticalSection());
|
||
|
|
||
|
//==============================================================
|
||
|
// Clear previous Error Object for this thread
|
||
|
//==============================================================
|
||
|
g_pCError->ClearErrorInfo();
|
||
|
|
||
|
if(cParamNames != 0)
|
||
|
{
|
||
|
if (rgParamNames == NULL || rgParamOrdinals == NULL){
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
else
|
||
|
//==============================================================
|
||
|
// If the consumer has not supplied parameter information.
|
||
|
//==============================================================
|
||
|
if ( m_pcmd->m_pQuery->GetParamCount() == 0 ){
|
||
|
|
||
|
//==========================================================
|
||
|
// Command Text must be set
|
||
|
//==========================================================
|
||
|
if (!(m_pcmd->m_pQuery->GetStatus() & CMD_TEXT_SET)){
|
||
|
hr = DB_E_NOCOMMAND;
|
||
|
}
|
||
|
else
|
||
|
//==========================================================
|
||
|
// Command Object must be in prepared state
|
||
|
//==========================================================
|
||
|
if ( !(m_pcmd->m_pQuery->GetStatus() & CMD_READY) ){
|
||
|
hr = DB_E_NOTPREPARED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = m_pcmd->MapParameterNames(cParamNames, rgParamNames, rgParamOrdinals, &IID_ICommandWithParameters);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hr = hr == S_OK ? hr : g_pCError->PostHResult(hr,&IID_ICommandWithParameters);
|
||
|
|
||
|
CATCH_BLOCK_HRESULT(hr,L"ICommandWithParameters::MapParameterNames");
|
||
|
return hr;
|
||
|
}
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Override the provider's parameter information.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CImpICommandWithParameters::SetParameterInfo( DB_UPARAMS cParams, const DB_UPARAMS rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[] )
|
||
|
{
|
||
|
ULONG i;
|
||
|
BOOL fNamedParams = (cParams > 0) ? TRUE : FALSE;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
CSetStructuredExceptionHandler seh;
|
||
|
|
||
|
TRY_BLOCK;
|
||
|
|
||
|
//=========================================================
|
||
|
// Serialize access
|
||
|
//=========================================================
|
||
|
CAutoBlock cab(m_pcmd->GetCriticalSection());
|
||
|
|
||
|
//===================================================================
|
||
|
// Clear previous Error Object for this thread
|
||
|
//===================================================================
|
||
|
g_pCError->ClearErrorInfo();
|
||
|
|
||
|
if ( (cParams != 0) && (rgParamOrdinals == NULL) ){
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//===================================================================
|
||
|
// Scan for invalid arguments in the arrays
|
||
|
//===================================================================
|
||
|
for( i = 0; i < cParams; i++ ){
|
||
|
if ( !rgParamOrdinals[i] || (rgParamBindInfo && !(rgParamBindInfo[i].pwszDataSourceType)) ) {
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
else
|
||
|
if (rgParamBindInfo && rgParamBindInfo[i].pwszName == NULL)
|
||
|
{
|
||
|
fNamedParams = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr))
|
||
|
{
|
||
|
//===================================================================
|
||
|
// Don't allow parameters to be set if we've got a rowset open
|
||
|
//===================================================================
|
||
|
if ( m_pcmd->IsRowsetOpen() ){
|
||
|
hr = DB_E_OBJECTOPEN;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//===================================================================
|
||
|
// Need to unprepare the statement when parameter info is changed and
|
||
|
// set named params
|
||
|
//===================================================================
|
||
|
if ((m_pcmd->m_pQuery->GetStatus() & CMD_READY) && m_pcmd->m_pQuery->GetParamCount() > 0 && fNamedParams){
|
||
|
m_pcmd->UnprepareHelper(UNPREPARE_RESET_STMT);
|
||
|
}
|
||
|
|
||
|
hr = m_pcmd->SetParameterInfo(cParams, rgParamOrdinals, rgParamBindInfo);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hr = hr == S_OK ? hr : g_pCError->PostHResult(hr,&IID_ICommandWithParameters);
|
||
|
|
||
|
CATCH_BLOCK_HRESULT(hr,L"ICommandWithParameters::SetParameterInfo");
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Get a list of the command's parameters, their names, and their required types.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CCommand::GetParameterInfo( DB_UPARAMS* pcParams, DBPARAMINFO** prgDBParamInfo, WCHAR** ppNamesBuffer, const IID* piid )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
SHORT sw = 0;
|
||
|
ULONG cNumParams = 0;
|
||
|
ULONG cbNames = 0;
|
||
|
DBPARAMINFO* pTempInfo;
|
||
|
WCHAR* pwszNameBuffer;
|
||
|
PPARAMINFO pParamInfo;
|
||
|
ULONG iParam;
|
||
|
|
||
|
//=================================================================================
|
||
|
// If the consumer has set info for at least one parameter,
|
||
|
// we only return info on the parameters set by the consumer
|
||
|
//=================================================================================
|
||
|
if (m_pQuery->GetParamCount() > 0){
|
||
|
|
||
|
//=============================================================================
|
||
|
// Count the params set by the consumer
|
||
|
//=============================================================================
|
||
|
cNumParams = 0;
|
||
|
for (iParam = 0; iParam <(unsigned) m_pQuery->GetParamCount(); iParam++){
|
||
|
pParamInfo = (PPARAMINFO)m_pQuery->GetParam(iParam);
|
||
|
if (pParamInfo){
|
||
|
cNumParams++;
|
||
|
if (ppNamesBuffer && pParamInfo->pwszParamName)
|
||
|
cbNames += (wcslen(pParamInfo->pwszParamName)+1)*sizeof(WCHAR);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
if (!m_pQuery->m_prgProviderParamInfo && m_pQuery->GetParamCount()){
|
||
|
|
||
|
//=========================================================================
|
||
|
// Get the parameter info
|
||
|
//=========================================================================
|
||
|
hr = GetParamInfo(piid);
|
||
|
}
|
||
|
|
||
|
if( hr == S_OK ){
|
||
|
cNumParams = m_pQuery->GetParamCount();
|
||
|
if (ppNamesBuffer){
|
||
|
|
||
|
for (iParam = 0; iParam < cNumParams; iParam++){
|
||
|
pParamInfo = m_pQuery->m_prgProviderParamInfo + iParam;
|
||
|
if (pParamInfo->pwszParamName)
|
||
|
cbNames += (wcslen(pParamInfo->pwszParamName)+1)*sizeof(WCHAR);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==================================================================================
|
||
|
// Check if we have any parameters
|
||
|
//==================================================================================
|
||
|
if ( cNumParams ){
|
||
|
|
||
|
//==============================================================================
|
||
|
// Allocate memory to return the information
|
||
|
//==============================================================================
|
||
|
*prgDBParamInfo = (DBPARAMINFO*)g_pIMalloc->Alloc(cNumParams*sizeof(DBPARAMINFO));
|
||
|
if ( !*prgDBParamInfo ){
|
||
|
hr = g_pCError->PostHResult(E_OUTOFMEMORY, piid);
|
||
|
}
|
||
|
else{
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
if (cbNames){
|
||
|
|
||
|
*ppNamesBuffer = (WCHAR*)g_pIMalloc->Alloc(cbNames);
|
||
|
if (!*ppNamesBuffer){
|
||
|
hr = g_pCError->PostHResult(E_OUTOFMEMORY, piid);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( S_OK == hr ){
|
||
|
|
||
|
//======================================================================
|
||
|
// Initialize memory
|
||
|
//======================================================================
|
||
|
memset(*prgDBParamInfo, 0, (cNumParams*sizeof(DBPARAMINFO)));
|
||
|
|
||
|
//======================================================================
|
||
|
// Describe the Parameter Markers
|
||
|
//======================================================================
|
||
|
if (m_pQuery->GetParamCount() > 0){
|
||
|
|
||
|
//==================================================================
|
||
|
// Return the parameter information set by the consumer
|
||
|
//==================================================================
|
||
|
pwszNameBuffer = ppNamesBuffer? *ppNamesBuffer : NULL;
|
||
|
pTempInfo = *prgDBParamInfo;
|
||
|
|
||
|
for (iParam = 0; iParam < (unsigned)m_pQuery->GetParamCount(); iParam++) {
|
||
|
|
||
|
pParamInfo = (PPARAMINFO) m_pQuery->GetParam(iParam);
|
||
|
if (!pParamInfo)
|
||
|
continue;
|
||
|
|
||
|
//==============================================================
|
||
|
// Fill 'er up
|
||
|
//==============================================================
|
||
|
pTempInfo->dwFlags = pParamInfo->dwFlags;
|
||
|
pTempInfo->iOrdinal = iParam+1;
|
||
|
if (pwszNameBuffer && pParamInfo->pwszParamName) {
|
||
|
pTempInfo->pwszName = pwszNameBuffer;
|
||
|
wcscpy(pwszNameBuffer, pParamInfo->pwszParamName);
|
||
|
pwszNameBuffer += wcslen(pParamInfo->pwszParamName) + 1;
|
||
|
}
|
||
|
//==============================================================
|
||
|
// pTempInfo->pTypeInfo already NULL
|
||
|
//==============================================================
|
||
|
pTempInfo->ulParamSize = pParamInfo->ulParamSize;
|
||
|
pTempInfo->wType = pParamInfo->wOLEDBType,
|
||
|
pTempInfo++;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
|
||
|
//==================================================================
|
||
|
// Return the parameter information derived from the command.
|
||
|
//==================================================================
|
||
|
pwszNameBuffer = ppNamesBuffer? *ppNamesBuffer : NULL;
|
||
|
pTempInfo = *prgDBParamInfo;
|
||
|
for (iParam = 0; iParam <(ULONG) m_pQuery->GetParamCount(); iParam++){
|
||
|
pParamInfo = m_pQuery->m_prgProviderParamInfo + iParam;
|
||
|
|
||
|
//==============================================================
|
||
|
// Fill 'er up
|
||
|
//==============================================================
|
||
|
pTempInfo->dwFlags = pParamInfo->dwFlags;
|
||
|
pTempInfo->iOrdinal = iParam+1;
|
||
|
if (pwszNameBuffer && pParamInfo->pwszParamName){
|
||
|
pTempInfo->pwszName = pwszNameBuffer;
|
||
|
wcscpy(pwszNameBuffer, pParamInfo->pwszParamName);
|
||
|
pwszNameBuffer += wcslen(pParamInfo->pwszParamName) + 1;
|
||
|
}
|
||
|
//==============================================================
|
||
|
// pTempInfo->pTypeInfo already NULL
|
||
|
//==============================================================
|
||
|
pTempInfo->ulParamSize = pParamInfo->ulParamSize;
|
||
|
pTempInfo->wType = pParamInfo->wOLEDBType,
|
||
|
pTempInfo++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( SUCCEEDED(hr) ){
|
||
|
*pcParams = cNumParams;
|
||
|
}
|
||
|
else{
|
||
|
*pcParams = 0;
|
||
|
if (*prgDBParamInfo){
|
||
|
g_pIMalloc->Free(*prgDBParamInfo);
|
||
|
*prgDBParamInfo = NULL;
|
||
|
}
|
||
|
if (ppNamesBuffer && *ppNamesBuffer){
|
||
|
g_pIMalloc->Free(*ppNamesBuffer);
|
||
|
ppNamesBuffer = NULL;
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// This method allows client to define the parameters.
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CCommand::SetParameterInfo( DB_UPARAMS cParams, const DB_UPARAMS rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[] )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
PPARAMINFO pParamInfo = NULL;
|
||
|
DBORDINAL iMax = 0;
|
||
|
DBORDINAL iParams;
|
||
|
CDataMap DataMap;
|
||
|
DBTYPE wDataType = 0;
|
||
|
BOOL bOveridden = FALSE;
|
||
|
BOOL bRet = FALSE;
|
||
|
//=====================================================================
|
||
|
// If given no params, discard all user param info and return
|
||
|
//=====================================================================
|
||
|
if (!cParams){
|
||
|
m_pQuery->DeleteConsumerParamInfo();
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//=====================================================================
|
||
|
// If there's no rgParamBindInfo, we're to discard the param information
|
||
|
//=====================================================================
|
||
|
if ( !rgParamBindInfo ){
|
||
|
|
||
|
ULONG_PTR iElem = 0;
|
||
|
//=================================================================
|
||
|
// Discard the param info
|
||
|
//=================================================================
|
||
|
for (iParams = 0; iParams < cParams; iParams++){
|
||
|
|
||
|
iElem = rgParamOrdinals[iParams];
|
||
|
if (iElem > 0 && iElem <= (unsigned)m_pQuery->GetParamCount()){
|
||
|
|
||
|
m_pQuery->RemoveParam(iElem-1);
|
||
|
delete pParamInfo;
|
||
|
}
|
||
|
}
|
||
|
hr = S_OK;
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
|
||
|
//=====================================================================
|
||
|
// Find the max param ordinal and check for valid param names
|
||
|
//=====================================================================
|
||
|
iMax = rgParamOrdinals[0];
|
||
|
for (iParams = 0; iParams < cParams; iParams++){
|
||
|
|
||
|
if (iMax < rgParamOrdinals[iParams])
|
||
|
{
|
||
|
iMax = rgParamOrdinals[iParams];
|
||
|
}
|
||
|
|
||
|
if(rgParamBindInfo[iParams].pwszName != NULL)
|
||
|
/* {
|
||
|
hr = DB_E_BADPARAMETERNAME;
|
||
|
}
|
||
|
else
|
||
|
*/ if (wcslen(rgParamBindInfo[iParams].pwszName )== 0){
|
||
|
hr = DB_E_BADPARAMETERNAME;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr))
|
||
|
{
|
||
|
DBORDINAL iOrdinal;
|
||
|
//=====================================================================
|
||
|
// Loop over bind info and set or override the param info
|
||
|
//=====================================================================
|
||
|
for (iParams = 0; iParams < cParams; iParams++){
|
||
|
|
||
|
iOrdinal = rgParamOrdinals[iParams];
|
||
|
//=================================================================
|
||
|
// Add the consumer-provided information to our cache
|
||
|
//=================================================================
|
||
|
try
|
||
|
{
|
||
|
pParamInfo = new PARAMINFO;
|
||
|
}
|
||
|
catch(...)
|
||
|
{
|
||
|
SAFE_DELETE_PTR(pParamInfo);
|
||
|
throw;
|
||
|
}
|
||
|
|
||
|
if (NULL == pParamInfo){
|
||
|
hr = (E_OUTOFMEMORY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pParamInfo->dwFlags = rgParamBindInfo[iParams].dwFlags;
|
||
|
pParamInfo->ulParamSize = rgParamBindInfo[iParams].ulParamSize;
|
||
|
pParamInfo->iOrdinal = iOrdinal;
|
||
|
|
||
|
DataMap.TranslateParameterStringToOLEDBType( wDataType, rgParamBindInfo[iParams].pwszDataSourceType);
|
||
|
pParamInfo->wOLEDBType = wDataType;
|
||
|
|
||
|
if (rgParamBindInfo[iParams].pwszName){
|
||
|
ULONG cwchName = wcslen(rgParamBindInfo[iParams].pwszName);
|
||
|
try
|
||
|
{
|
||
|
pParamInfo->pwszParamName = new WCHAR[cwchName+1];
|
||
|
}
|
||
|
catch(...)
|
||
|
{
|
||
|
SAFE_DELETE_ARRAY(pParamInfo->pwszParamName);
|
||
|
throw;
|
||
|
}
|
||
|
|
||
|
if (NULL == pParamInfo->pwszParamName){
|
||
|
SAFE_DELETE_PTR(pParamInfo);
|
||
|
hr = (E_OUTOFMEMORY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
wcscpy(pParamInfo->pwszParamName,rgParamBindInfo[iParams].pwszName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr))
|
||
|
{
|
||
|
// Remove the parameter if a parameter alread exist at the ordinal
|
||
|
if (iOrdinal > 0 && iOrdinal <= (unsigned)m_pQuery->GetParamCount()){
|
||
|
|
||
|
m_pQuery->RemoveParam(iOrdinal-1);
|
||
|
SAFE_DELETE_ARRAY(pParamInfo->pwszParamName);
|
||
|
SAFE_DELETE_PTR(pParamInfo);
|
||
|
bOveridden = TRUE;
|
||
|
}
|
||
|
// If there is already a parameter at this ordinal , remove
|
||
|
// that and insert this new one
|
||
|
hr = m_pQuery->AddConsumerParamInfo(iOrdinal-1,pParamInfo);
|
||
|
if( FAILED(hr)){
|
||
|
break;
|
||
|
}
|
||
|
if( hr == S_OK && bOveridden == TRUE)
|
||
|
{
|
||
|
hr = DB_S_TYPEINFOOVERRIDDEN;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} // for loop
|
||
|
|
||
|
|
||
|
} // If succeeded(hr)
|
||
|
}
|
||
|
|
||
|
|
||
|
hr = hr == S_OK ? hr : g_pCError->PostHResult(hr, &IID_ICommandWithParameters);
|
||
|
return hr;
|
||
|
}
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Gets the parameter information for each param marker present in the command.
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CCommand::GetParamInfo( const IID *piid )
|
||
|
{
|
||
|
PPARAMINFO prgParamInfo = NULL;
|
||
|
|
||
|
if (m_CError.Size())
|
||
|
{
|
||
|
m_CError.FreeErrors();
|
||
|
}
|
||
|
|
||
|
m_pQuery->SetProviderParamInfo(prgParamInfo);
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CCommand::MapParameterNames( DB_UPARAMS cParamNames, const OLECHAR* rgParamNames[], DB_LPARAMS rgParamOrdinals[],
|
||
|
const IID* piid )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
ULONG iName = 0;
|
||
|
ULONG iParam = 0;
|
||
|
ULONG cParam = 0;
|
||
|
ULONG cErrors = 0;
|
||
|
|
||
|
//=======================================================
|
||
|
// Check if we have any parameters
|
||
|
//=======================================================
|
||
|
if ( cParamNames )
|
||
|
{
|
||
|
cParam = m_pQuery->GetParamCount();
|
||
|
|
||
|
if (cParam > 0){
|
||
|
|
||
|
for (iName = 0; iName < cParamNames; iName++){
|
||
|
|
||
|
for (iParam = 0; iParam < cParam; iParam++){
|
||
|
|
||
|
PPARAMINFO pParamInfo;
|
||
|
pParamInfo = (PPARAMINFO) m_pQuery->GetParam(iParam);
|
||
|
if (pParamInfo && pParamInfo->pwszParamName && !_wcsicmp(rgParamNames[iName],pParamInfo->pwszParamName)){
|
||
|
|
||
|
rgParamOrdinals[iName] = LONG(iParam + 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (iParam == cParam){
|
||
|
rgParamOrdinals[iName] = 0;
|
||
|
cErrors++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
|
||
|
if (!m_pQuery->m_prgProviderParamInfo && m_pQuery->GetParamCount() && !(m_pQuery->GetStatus())){
|
||
|
|
||
|
//=======================================================
|
||
|
// Get the parameter info
|
||
|
//=======================================================
|
||
|
if (SUCCEEDED(hr = GetParamInfo(piid))){
|
||
|
|
||
|
cParam = m_pQuery->GetParamCount();
|
||
|
for (iName = 0; iName < cParamNames; iName++) {
|
||
|
|
||
|
for (iParam = rgParamNames[iName]? 0 : cParam; iParam < cParam; iParam++){
|
||
|
|
||
|
PPARAMINFO pParamInfo = m_pQuery->m_prgProviderParamInfo + iParam;
|
||
|
if (pParamInfo->pwszParamName && !_wcsicmp(rgParamNames[iName],pParamInfo->pwszParamName)){
|
||
|
rgParamOrdinals[iName] = LONG(iParam + 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (iParam == cParam) {
|
||
|
rgParamOrdinals[iName] = 0;
|
||
|
cErrors++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!cErrors)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else if (cErrors < cParamNames)
|
||
|
{
|
||
|
hr = DB_S_ERRORSOCCURRED;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = DB_E_ERRORSOCCURRED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hr = hr == S_OK ? hr : g_pCError->PostHResult(hr, &IID_ICommandWithParameters);
|
||
|
return hr;
|
||
|
}
|