BUG: Access Violation in Application That Calls CManualAccessor::AddParameterEntry

ID: Q240364


The information in this article applies to:
  • Microsoft Visual C++, 32-bit Editions, version 6.0


SYMPTOMS

When the CCommand::Open function is called, an access violation may occur when this function calls ICommand::Execute. This problem occurs when CManualAccessor is used for the accessor class and AddParameterEntry is called with the fifth argument (the pLength argument) set to something other than NULL.


CAUSE

There is a bug in the CManualAccesor::AddParameterEntry method. In this function, the nLengthOffset value is incorrectly calculated. Here is the code:


void AddParameterEntry(ULONG nOrdinal, DBTYPE wType, ULONG nColumnSize,
			void* pData, void* pLength = NULL, void* pStatus = NULL,
			DBPARAMIO eParamIO = DBPARAMIO_INPUT)
	{
		ATLASSERT(m_nCurrentParameter < m_nParameters);
		ULONG   nLengthOffset, nStatusOffset;

		if (pStatus != NULL)
			nStatusOffset = (BYTE*)pStatus - m_pParameterBuffer;
		else
			nStatusOffset = 0;

		if (pLength != NULL)
			nLengthOffset = (BYTE*)pLength - m_pBuffer;
		else
			nLengthOffset = 0;

		Bind(m_pParameterEntry + m_nCurrentParameter, nOrdinal, wType, nColumnSize, 0, 0,
			eParamIO, (BYTE*)pData - m_pParameterBuffer, nLengthOffset, nStatusOffset);

		m_nCurrentParameter++;
	} 


RESOLUTION

The code in the "Cause" section should be changed to the following:


void AddParameterEntry(ULONG nOrdinal, DBTYPE wType, ULONG nColumnSize,
			void* pData, void* pLength = NULL, void* pStatus = NULL,
			DBPARAMIO eParamIO = DBPARAMIO_INPUT)
	{
		ATLASSERT(m_nCurrentParameter < m_nParameters);
		ULONG   nLengthOffset, nStatusOffset;

		if (pStatus != NULL)
			nStatusOffset = (BYTE*)pStatus - m_pParameterBuffer;
		else
			nStatusOffset = 0;

		if (pLength != NULL)
			nLengthOffset = (BYTE*)pLength - m_pParameterBuffer;/*m_pBuffer;*/ 
		else
			nLengthOffset = 0;

		Bind(m_pParameterEntry + m_nCurrentParameter, nOrdinal, wType, nColumnSize, 0, 0,
			eParamIO, (BYTE*)pData - m_pParameterBuffer, nLengthOffset, nStatusOffset);

		m_nCurrentParameter++;
	} 
Note that the m_pBuffer variable is replaced with m_pParameterBuffer.

To make the correction, you can either modify the Atldbcli.h file or create a new AddParameterEntry function that has the modification. For example, you might have a CCommand-derived class that resembles the following:

class CMyCmd: public CCommand< CManualAccessor, CNoRowset >
{

public:

	void AddParameterEntry(ULONG nOrdinal, DBTYPE wType, ULONG nColumnSize,
			void* pData, void* pLength = NULL, void* pStatus = NULL,
			DBPARAMIO eParamIO = DBPARAMIO_INPUT)
	{
		ATLASSERT(m_nCurrentParameter < m_nParameters);
		ULONG   nLengthOffset, nStatusOffset;

		if (pStatus != NULL)
			nStatusOffset = (BYTE*)pStatus - m_pParameterBuffer;
		else
			nStatusOffset = 0;

		if (pLength != NULL)
			nLengthOffset = (BYTE*)pLength - m_pParameterBuffer;/*m_pBuffer*/ 
		else
			nLengthOffset = 0;

		CManualAccessor::Bind(m_pParameterEntry + m_nCurrentParameter, nOrdinal, wType, nColumnSize, 0, 0,
			eParamIO, (BYTE*)pData - m_pParameterBuffer, nLengthOffset, nStatusOffset);

		m_nCurrentParameter++;
	}
}; 


STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.


MORE INFORMATION

Steps to Reproduce Behavior

The following code demonstrates how to reproduce the problem:

...
	CSession session ;
	hr = session.Open( ds ) ;
	
	CCommand< CManualAccessor, CNoRowset > cmd ;<BR/>
	cmd.Create( session, NULL);
	cmd.CreateParameterAccessor( 2, &buf, sizeof(buf) );
	cmd.AddParameterEntry( 1, DBTYPE_I4,0, &buf, NULL, NULL, DBPARAMIO_INPUT );
	cmd.AddParameterEntry( 2, DBTYPE_STR, 32, (PBYTE)&buf + 4, (PBYTE)&buf + 36 , NULL, DBPARAMIO_OUTPUT );

	if( SUCCEEDED( hr = cmd.Open(session, "{call sp_myproc(?,?)}", NULL, &lRows, DBGUID_DEFAULT, false)  ) )
			{
... 

Additional query words: AV first chance exception

Keywords : kbtemplate kbDatabase kbDTL kbOLEDB kbVC kbVC600bug kbGrpVCDB kbDSupport
Version : winnt:6.0
Platform : winnt
Issue type : kbbug


Last Reviewed: December 3, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.