// mtbs.cpp #define _WIN32_DCOM #define INITGUID #include "iadmw.h" // COM Interface header #include "iiscnfg.h" // MD_ & IIS_MD_ #defines #include #include class CSink : public IMSAdminBaseSink { public: // IUnknown ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppv); // IMSAdminBaseSink HRESULT STDMETHODCALLTYPE ShutdownNotify( void); HRESULT STDMETHODCALLTYPE SinkNotify( DWORD dwMDNumElements, MD_CHANGE_OBJECT pcoChangeList[]); CSink() : m_cRef(0) { } ~CSink() { } private: long m_cRef; }; ULONG CSink::AddRef() { return ++m_cRef; } ULONG CSink::Release() { if(--m_cRef != 0) return m_cRef; delete this; return 0; } HRESULT CSink::QueryInterface(REFIID riid, void** ppv) { if(riid == IID_IUnknown) { *ppv = (IUnknown*)this; } else if(riid == IID_IMSAdminBaseSink ) { *ppv = (IMSAdminBaseSink*)this; } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } HRESULT CSink::ShutdownNotify() { printf( "CSink::ShutdownNotify is called\n"); return S_OK; } HRESULT CSink::SinkNotify( DWORD dwMDNumElements, MD_CHANGE_OBJECT pcoChangeList[]) { DWORD i, j; printf( "CSink::SinkNotify is called\n"); for (i=0; iFindConnectionPoint(IID_IMSAdminBaseSink, &pConnectionPoint); if(FAILED(hr)) { printf("Failed to get IConnectionPoint interface pointer\n"); pConnectionPointContainer->Release(); return ; } //establish event notification with iis metabase CSink* mySink = new CSink; DWORD dwCookie; hr=pConnectionPoint->Advise((IUnknown*)mySink, &dwCookie); printf("CLIENT CALLED ADVISE\n"); printf("Press any key to exit\n"); _getch(); //Unadvise will call mySink's Release() function //and delete mySink Object. So DO NOT call delete mySink hr=pConnectionPoint->Unadvise(dwCookie); pConnectionPoint->Release(); pConnectionPointContainer->Release(); }