BUG: IDispatch:GetIDsOfNames function may return E_FAIL even when the call succeeds

Article translations Article translations
Article ID: 266713 - View products that this article applies to.
This article was previously published under Q266713
Expand all | Collapse all


The way that ATL implements the IDispatch::GetIDsOfNames function may result in E_FAIL being returned, even when the call succeeds.


When multiple threads call into an object's IDispatch::GetIDsOfNames function, the CComTypeInfoHolder::GetTI function is eventually called to load the type library and get the ITypeInfo interface. Because loading the type library and retrieving the interface are protected by a critical section, the second thread waits for the first thread to finish. Once the first thread releases the critical section, the second thread enters the critical section, finds m_pInfo is non-NULL (set by the first thread), and returns the hRes, which is set to E_FAIL. The IDispatch::GetIDsNames function eventually returns this E_FAIL.


To work around this problem, the CComTypeInfoHolder::GetTI function in the Atlcom.h file must be modified as follows (all changes are marked with the comments "ADD" and "END ADD"):
inline HRESULT CComTypeInfoHolder::GetTI(LCID lcid)
   // If this assert occurs, probably didn't initialize properly.
   ATLASSERT(m_plibid != NULL && m_pguid != NULL);
   ATLASSERT(!InlineIsEqualGUID(*m_plibid, GUID_NULL)
       && "Did you forget to pass the LIBID to CComModule::Init?");

   if (m_pInfo != NULL)
      return S_OK;
   if (m_pInfo == NULL)
      ITypeLib* pTypeLib;
      hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);
      if (SUCCEEDED(hRes))
	 CComPtr<ITypeInfo> spTypeInfo;
	 hRes = pTypeLib->GetTypeInfoOfGuid(*m_pguid, &spTypeInfo);
	 if (SUCCEEDED(hRes))
	    CComPtr<ITypeInfo> spInfo(spTypeInfo);
	    CComPtr<ITypeInfo2> spTypeInfo2;
	    if (SUCCEEDED(spTypeInfo->QueryInterface(&spTypeInfo2)))
	        spInfo = spTypeInfo2;

	    m_pInfo = spInfo.Detach();
 	hRes = S_OK;
    //END ADD
    _Module.AddTermFunc(Cleanup, (DWORD)this);
    return hRes;
Make these modifications to a copy of the Atlcom.h file (for example, Fixatlcom.h). Comment out Atlcom.h in the Stdafx.h file, and then use Fixatlcom.h instead, as follows:
//#include <atlcom.h>
#include "FixAtlCom.h"


Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the "Applies to" section.


Article ID: 266713 - Last Review: September 26, 2005 - Revision: 3.1
  • Microsoft ActiveX Template Library 3.0, when used with:
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
kbbug kbqfe kbpending kbhotfixserver KB266713

Give Feedback


Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com