Microsoft KB Archive/230276

= FIX: ADO Recordset GetString Function Throws an Access Violation in Oleaut32.dll =

Article ID: 230276

Article Last Modified on 11/4/2003

-

APPLIES TO


 * Microsoft ActiveX Data Objects 2.0
 * Microsoft ActiveX Data Objects 2.1
 * Microsoft Visual C++ 6.0 Enterprise Edition

-



This article was previously published under Q230276



SYMPTOMS
Calling the GetString function on a _RecordsetPtr object may cause the following error to occur:

Unhandled Exception in (OLEAUT32.DLL) : 0xC0000005: Access Violation



CAUSE
The #import-generated wrapper function GetString passes an uninitialized BSTR pointer to the ADO raw_GetString function as an out parameter. The raw_GetString function incorrectly calls the SysFreeString function on the parameter if it is not pointing to NULL.



RESOLUTION
This problem was corrected in ADO 2.5.

For earlier versions of ADO, call the raw_GetString directly and pass a BSTR pointer that points to NULL as the output parameter, or create a wrapper function as described in the "More Information" section.



STATUS
Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

This problem was corrected in ADO 2.5.



Steps to Reproduce the Behavior
These steps use the SQL Server Pubs database:

 Create a Win32 console application (Simple application) in Visual C++.  Paste the following code to replace code generated in the .cpp file:

Note You must change User ID= and Password = to the correct values before you run this code. Make sure that User ID has the appropriate permissions to perform this operation on the database.
 * 1) include "stdafx.h"
 * 2) include 


 * 1) import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename( "EOF", "adoEOF" )

struct InitOle { InitOle { ::CoInitialize(NULL); } ~InitOle { ::CoUninitialize;  } } _init_InitOle_;

int main(int argc, char* argv[]) {

try { _ConnectionPtr pCon(__uuidof(Connection)); _RecordsetPtr pRs(__uuidof(Recordset));

pCon->ConnectionString = L"Provider=SQLOLEDB.1; Server=(local);Initial Catalog=pubs; User Id= ; Password= ;"; pCon->Open(L"",L"",L"",-1);

pRs->Open(L"SELECT * FROM authors",pCon.GetInterfacePtr,adOpenStatic,adLockOptimistic,-1);

_bstr_t btRecordset; btRecordset = pRs->GetString(adClipString,-1,L",",L"\r\n",L""); cout << (char*) btRecordset << endl; }   catch (_com_error& e)    { cout << e.ErrorMessage << endl; }

return 0; }

 Run the code and observe the results.

Resolution
<ul> Use ADO 2.5 -or-

</li>  Call the raw_GetString function directly with a BSTR pointer that is initialized to point to NULL.

Use the following code to replace the call to GetString:

BSTR bstrResult = NULL; _bstr_t btColDelim(L","); _bstr_t btRowDelim(L"\r\n"); _bstr_t btNullExp(L"<NULL>"); HRESULT hr = pRs->raw_GetString(adClipString,-1,btColDelim,btRowDelim,btNullExp,&bstrResult); if (FAILED(hr)) _com_issue_errorex(hr, pRs, __uuidof(pRs)); btRecordset = bstrResult;

-or- </li>  Create an inline function similar to GetString that calls the raw_GetString function, but initialize the BSTR variable to NULL.

Note: Do not modify the generated .tli file to make the changes directly to the GetString wrapper implementation because this file is gegenerated at compile time. Instead, use the function below or copy and paste the GetString function from the .tli file and modify it as follows: inline _bstr_t GetString2 ( _RecordsetPtr pRs, enum StringFormatEnum StringFormat, long NumRows, _bstr_t ColumnDelimeter, _bstr_t RowDelimeter, _bstr_t NullExpr ) {   BSTR _result = NULL; HRESULT _hr = pRs->raw_GetString(StringFormat, NumRows, ColumnDelimeter, RowDelimeter, NullExpr, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, pRs, __uuidof(pRs)); return _bstr_t(_result, false); }

You can call this function in the main function as follows: btRecordset = GetString2(pRs,adClipString,-1,L",",L"\r\n",L"<NULL>"); </li></ul>

Additional query words: mdac

Keywords: kbbug kbfix kbdatabase kbmdacnosweep kbado250fix KB230276

-

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

© Microsoft Corporation. All rights reserved.