FIX: _AfxDispatchPushArgs Incorrectly AddRef's Invoke Argument

Last reviewed: September 18, 1997
Article ID: Q123274
1.50 WINDOWS kbole kbbuglist kbfixlist

The information in this article applies to:

  • The Microsoft Foundation Classes (MFC), included with

        - Microsoft Visual C++ for Windows, version 1.5
    

SYMPTOMS

The CCmdTarget::InvokeHelper member function uses an internal helper function _AfxDispatchPushArgs to set up the arguments to be passed eventually to IDispatch::Invoke on the OLE Automation object.

If OLE objects are passed as arguments by value, the user may see memory leaks due to these objects not being freed after being passed to _AfxDispatchPushArgs.

CAUSE

When _AfxDispatchPushArgs trys to change parameters passed by reference into the appropriate type, an extra AddRef is performed on the object by the VariantChangeType API. Consequently those objects do not shutdown correctly.

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 Microsoft Visual C++ 1.51 for Windows.

MORE INFORMATION

Below is the original section followed by the fixed version of _AfxDispatchPushArgs responsible for changing the parameter data (OLEDISP1.CPP 546-559).

=== ORIGINAL VERSION === if (vt != VT_VARIANT && vt != pArg->vt) {

    VariantInit(&va);

    // argument is not of appropriate type, attempt to coerce it
    //
    // BUG: the VariantChangeType actually does an AddRef if pArg
    // is an LPDISPATCH or LPUNKNOWN parameter
    //
    if (VariantChangeType(&va, pArg, 0, vt) != NOERROR)
    {
        // argument could not be coerced
   *puArgErr = iArg;
   return DISP_E_TYPEMISMATCH;
    }
    ASSERT(va.vt == vt);
    pArg = &va;
}

=== FIXED VERSION === NOTE: rgTempVars in the following code is a list of temporary VARIANT objects supplied, and explicitly cleaned up, by CCmdTarget::InvokeHelper to be used for the VariantChangeType API.

if (vt != VT_VARIANT && vt != pArg->vt) {

    // argument is not of appropriate type, attempt to coerce it
    LPVARIANT pArgTemp = &rgTempVars[iArg];
    ASSERT(pArgTemp->vt == VT_EMPTY);
    SCODE sc = GetScode(VariantChangeType(pArgTemp, pArg, 0, vt));
    if (FAILED(sc))
    {
        // argument could not be coerced
        *puArgErr = iArg;
        return sc;
    }
    ASSERT(pArgTemp->vt == vt);
    pArg = pArgTemp;
}


Additional reference words: 1.50 2.50
KBCategory: kbole kbbuglist kbfixlist
KBSubcategory: MfcOLE
Keywords : kb16bitonly MfcOLE kbbuglist kbfixlist kbole
Technology : kbMfc
Version : 1.50
Platform : WINDOWS
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.

Last reviewed: September 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.