Cateodata e util (povestea lui “de ce” e prea lunga) sa se intercepteze apelurile care se fac intr-un server COM DLL 3rd party. Una dintre posibilele solutii la aceasta problema urmeaza:
(voi scurta detaliile, presupunand ca oricum daca nu stiti cum sa ajungeti aici, nu v-ati pus problema interceptiei COM anyway ).
1. New project, ATL project.
2. Cu ajutorul object viewerului, inspectati DLL-ul care va intereseaza; veti avea in COM Object Viewer IDL-ul serverului vizat. Copiati-l in proiectul nou.
3. Adaugati un obiect COM (simple COM object), care va implementa interfata/interfetele care va intereseaza.
4. Nu uitati sa actualizati resursele registry (rgs) cu UUID-urile din IDL-ul “pastat”.
5. Metodele FinalConstruct si Final Release din obiectul COM adaugat la punctul 3, ar putea arata asa:
(IMyInterface este interfata care se intercepteaza):
HMODULE m_hOriginalModule; // handle la DLL-ul interceptat
CComPtr
 HRESULT FinalConstruct()
 {
//Â incarca modulul de interceptat
  m_hOriginalModule = CoLoadLibrary(_T(“
  if(m_hOriginalModule != NULL)
  {
// obtine ptr la IClassFactory
   CComPtr
   DllGetClassObjectFn fn = (DllGetClassObjectFn)GetProcAddress(m_hOriginalModule, “DllGetClassObject”);
   if(fn != NULL)
   {
// apel DllGetClassObject in modulul interceptat, pentru a obtine IClassFactory-ulÂ
    HRESULT hRes = fn(CLSID_MyInterfaceCoClass, IID_IClassFactory, (LPVOID *)&pFactory); Â
    if(FAILED(hRes))
    {
     return hRes;
    }
 // apel CreateInstance pentru a obtine o interfata in implementarea originala
    hRes = pFactory->CreateInstance(NULL, IID_IMyInterface, (LPVOID *)&m_pOriginalInterface);
    if(FAILED(hRes))
    {
     return hRes;
    }
   } Â
  }
 Â
  return S_OK;
 }
 void FinalRelease()
 {
  if(m_hOriginalModule != NULL)
  {
// release inainte de FreeLibrary
   m_pOriginalInterface.Release();
   CoFreeLibrary(m_hOriginalModule);
  }
 }
// se poate rescrie functia InternalQueryInterface pentru a loga ce apeluri QI se fac Â
static HRESULT InternalQueryInterface(void *pThis, const ATL::_ATL_INTMAP_ENTRY *pEntries, const IID &iid, void **ppvObject)
 {
  // log the thing
  HRESULT hRes = CComObjectRootBase::InternalQueryInterface(pThis, pEntries, iid, ppvObject);
  CLog log;
  log.Write(“QI: {%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x} returned=%08x\r\n”,
   iid.Data1, iid.Data2, iid.Data3, iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3],
   iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7], hRes);
  return hRes;
 }
// se pot rescrie metodele din IMyInterface si loga parametrii
HRESULT MyMethod1(…. )
{
   // log params
   HRESULT hRes = m_pOriginalInterface->MyMethod1(…);
   // log hRes, out params
   return hRes;
}
… etc.