DOCUMENT:Q150789 30-JUL-2001 [visualc] TITLE :FIX: DFX_Bool Calls Default() with AFX_RFX_LONGBINARY PRODUCT :Microsoft C Compiler PROD/VER:winnt:4.0,4.1; : OPER/SYS: KEYWORDS:kbDAOsearch kbDatabase kbMFC kbVC ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - Microsoft Visual C++, versions 4.0, 4.1 - Microsoft Foundation Classes (MFC) ------------------------------------------------------------------------------- SYMPTOMS ======== Memory adjacent to the BOOL variable gets overwritten when working with a BOOL CDaoRecordset field data member. CAUSE ===== The DFX_Bool function delegates the Fixup case to CDaoFieldExchange::Default and incorrectly passes AFX_RFX_LONGBINARY as the field data type. RESOLUTION ========== To resolve this problem, copy the DFX_Bool function to the project and give it a different name. For example, rename it DFX_Bool2. In the call to CDaoFieldExchange::Default, change the field data type from AFX_RFX_LONGBINARY to AFX_RFX_BOOL by using the following code: Change this code case CDaoFieldExchange::Fixup: // Convert BOOL value from AFX_DAO_TRUE/FALSE to TRUE/FALSE value = (value != AFX_DAO_FALSE); pFX->Default(lpszName, (void*)&value, AFX_RFX_LONGBINARY, dwBindOptions); return; to this code: case CDaoFieldExchange::Fixup: // Convert BOOL value from AFX_DAO_TRUE/FALSE to TRUE/FALSE value = (value != AFX_DAO_FALSE); pFX->Default(lpszName, (void*)&value, AFX_RFX_BOOL, dwBindOptions); // <<-- Change to AFX_RFX_BOOL return; Then, change the class of the CDaoRecordset-derived DoFieldExchange function to call this new function in place of calling DFX_Bool. STATUS ====== Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This bug was corrected in Visual C++ 32-bit Edition version 4.2. MORE INFORMATION ================ The code for the Fixup case in CDaoFieldExchange::Default is: case Fixup: if (m_prs->GetFieldLength(m_nField-1) == DAO_NULL) { // Set the value to PSEUDO NULL and mark the status NULL SetNullValue(pv, dwColumnType); m_prs->SetNullFieldStatus(m_nField-1); } return; The dwColumn type is the variable that is incorrectly set to AFX_RFX_LONGBINARY in DFX_Bool. Note that SetNullValue is called with the value passed in the second parameter. The code for SetNullValue (showing relevant cases) is: void CDaoFieldExchange::SetNullValue(void* pv, DWORD dwDataType) { switch (dwDataType) { . . . case AFX_RFX_LONGBINARY: ((CLongBinary*)pv)->m_dwDataLength = 0; break; case AFX_RFX_BOOL: *(BOOL*)pv = AFX_RFX_BOOL_PSEUDO_NULL; break; . . . } } Note that the AFX_RFX_BOOL case (the one that should be called) sets the BOOL variable to the constant AFX_RFX_BOOL_PSEUDO_NULL. The AFX_RFX_LONGBINARY case (incorrectly called in the MFC source) sets the m_dwDataLength member of a CLongBinary object (at an offset in the object beyond the size of a BOOL) to zero. Whatever is adjacent to the BOOL variable has 4 bytes of its memory overwritten. The symptoms of this memory overwrite depend on what that variable was used for. There can also be no symptoms. Additional query words: kbVC400bug 4.00 4.10 4.20 vcfixlist420 MfcDAO ====================================================================== Keywords : kbDAOsearch kbDatabase kbMFC kbVC Technology : kbVCsearch kbVC400 kbAudDeveloper kbMFC kbVC410 Version : winnt:4.0,4.1; : Issue type : kbbug Solution Type : kbfix ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2001.