FIX: Access Violation in Application That Calls CManualAccessor::AddParameterEntry (240364)
The information in this article applies to:
- Microsoft OLE DB, when used with:
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 6.0
This article was previously published under Q240364 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++;
}
};
STATUSMicrosoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.
This problem was corrected in Microsoft Visual C++ .NET.
Modification Type: | Major | Last Reviewed: | 10/15/2002 |
---|
Keywords: | kbBug kbConsumer kbDatabase kbDSupport kbDTL kbMDACNoSweep kbNoUpdate kbtemplate KB240364 |
---|
|