Microsoft KB Archive/240364

= FIX: Access Violation in Application That Calls CManualAccessor::AddParameterEntry =

Article ID: 240364

Article Last Modified on 10/15/2002

-

APPLIES TO

 Microsoft OLE DB 2.7, when used with:  Microsoft Visual C++ 6.0 Enterprise Edition

 Microsoft Visual C++ 6.0 Professional Edition

 Microsoft Visual C++ 6.0 Standard Edition 

-

<div class="notice_section">

This article was previously published under Q240364

<div class="symptoms_section">

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.

<div class="cause_section">

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++; }

<div class="resolution_section">

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++; } };

<div class="status_section">

STATUS
Microsoft 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.

<div class="moreinformation_section">

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: kbbug kbfix kbnoupdate kbconsumer kbdatabase kbtemplate kbdtl kbmdacnosweep KB240364

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.