Microsoft KB Archive/123274

{|
 * width="100%"|

FIX: _AfxDispatchPushArgs Incorrectly AddRef's Invoke Argument

 * }

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 : kbole kb16bitonly kbMFC kbVC

Issue type :

Technology : kbAudDeveloper kbMFC