FIX: DAO 3.6 Causes Debug Errors in MFC DAO Non-Unicode Builds[visualc]
ID: Q235507
|
The information in this article applies to:
-
Microsoft Visual C++, 32-bit Editions, version 6.0
SYMPTOMS
When converting an MFC DAO application to use DAO 3.6 as described in the Knowledge Base article Q235507 PRB: Unrecognized Database Format Error with Access 2000 Database, the application can produce a debug error. This is the exact error message:
DAMAGE: after Normal block (#204) at <hex address>
CAUSE
DAO 3.6 incorrectly overwrites the character buffer supplied to it by MFC when it fetches text data. It first copies the Unicode string into the buffer that is twice as long as the length of the buffer and then converts the string to an Ansi string.
RESOLUTION
A supported fix that corrects this problem is now available from Microsoft, but
it has not been fully regression tested and should be applied only to systems
experiencing this specific problem. If you are not severely affected by this
specific problem, Microsoft recommends that you wait for the next Jet 3.51
Service Pack that contains this fix.
To resolve this problem immediately, contact Microsoft Product Support Services
to obtain the fix. For a complete list of Microsoft Product Support Services
phone numbers and information on support costs, please go to the following
address on the World Wide Web:
http://www.microsoft.com/support/supportnet/overview/overview.asp
This hotfix consists of the following file:
File Name Version
------------ -------------
DAO360.DLL 3.60.3315.0
To apply the hotfix, back up the existing copy of DAO360.DLL on the computer,
copy the hotfix version into the same location and register the dll using
regsvr32.exe as in the following example:
regsvr32 "C:\Program Files\common files\microsoft shared\dao\dao360.dll"
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
-
Create a new MFC application with database support using DAO and pointing to the Northwind.mdb sample database. Use the Employees table to base your recordset class.
-
Select Multiple Documents if necessary on step one.
-
Select Database View without file support on step two.
-
Click Data Source.
-
In the Database Options dialog box select DAO and specify the Northwind.mdb file in the corresponding edit box. Click OK on the Database Options dialog.
-
Select the Employees table from the list and click OK in the Select Database Tables dialog box.
-
Click Finish on step two of the wizard to accept default options and finish creating your project.
-
Insert the following line as the first line in your application's
InitInstance() method. This will load DAO 3.6 instead of DAO 3.5 as described in Knowledge Base article Q235507.
AfxGetModuleState()->m_dwVersion = 0x0601;
-
Build your application in the Win32 Debug configuration.
-
Run your application.
-
Click Move Next a few times. You will get a debug error similar to the one described above.
Workaround
-
Declare your own callback function in your application header file. It should be in the same file where your application class is declared.
STDAPI MyDaoStringAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
- Define the function in the implementation file where your application class is defined. This function is very similar to the function that MFC defines except it reallocates the CString internal buffer to twice the size that is needed.
STDAPI MyDaoStringAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
{
LPTSTR lpsz;
CString* pstr = (CString*)pData;
dwLen++;
TRY
{
//Allocate twice the space needed so that DAO does not overwrite the buffer
lpsz = pstr->GetBufferSetLength(2*dwLen/sizeof(TCHAR));
*ppv = (void*)(dwLen > 0 ? lpsz : NULL);
}
CATCH_ALL(e)
{
e->Delete();
return E_OUTOFMEMORY;
}
END_CATCH_ALL
return S_OK;
}
-
In your DoFieldExchange function for your recordset class, add the code below. This modifies the DAO binding structure for each field that is a text field so that the callback function is called instead of the MFC function. Insert the code after the calls to the RFX functions.
if (pFX->m_nOperation == CDaoFieldExchange::BindField)
{
for (int i=0;i<this->m_nFields;i++)
{
LPDAOCOLUMNBINDING pcb = &m_prgDaoColBindInfo[i];
if (pcb->dwDataType == DAO_CHAR)
{
pcb->cbDataOffset = (DWORD)MyDaoStringAllocCallback;
}
}
}
-
Compile your application.
-
Run the application.
-
Moving through the recordset does not produce errors.
REFERENCES
Q236991 PRB: Unrecognized Database Format Error with Access 2000 Database
Q236056 PRB: DAO 3.6 Overruns buffers in GetRowsEx method
Additional query words:
DAO AppWizard MFC MoveNext
Keywords : kbDatabase kbMFC kbVC600 kbGrpVCDB kbDAO360 kbDAO360bug
Version : winnt:6.0
Platform : winnt
Issue type : kbbug