// local.cpp #define _WIN32_DCOM #include #include #include "Component\component.h" // Generated by MIDL #include "registry.h" // Add This!!! long g_cComponents = 0; long g_cServerLocks = 0; HANDLE g_hEvent; IOutGoing* g_pOutGoing; class CInsideDCOM : public ISum, IConnectionPointContainer, IConnectionPoint { public: // IUnknown ULONG __stdcall AddRef(); ULONG __stdcall Release(); HRESULT __stdcall QueryInterface(REFIID iid, void** ppv); // IConnectionPointContainer HRESULT __stdcall EnumConnectionPoints(IEnumConnectionPoints** ppEnum); HRESULT __stdcall FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP); // IConnectionPoint HRESULT __stdcall GetConnectionInterface(IID* pIID); HRESULT __stdcall GetConnectionPointContainer(IConnectionPointContainer** ppCPC); HRESULT __stdcall Advise(IUnknown* pUnknown, DWORD* pdwCookie); HRESULT __stdcall Unadvise(DWORD dwCookie); HRESULT __stdcall EnumConnections(IEnumConnections** ppEnum); // ISum HRESULT __stdcall Sum(int x, int y, int* retval); CInsideDCOM() : m_cRef(0) { g_cComponents++; } ~CInsideDCOM() { cout << "Component: CInsideDCOM::~CInsideDCOM()" << endl, g_cComponents--; } private: long m_cRef; }; HRESULT CInsideDCOM::GetConnectionInterface(IID* pIID) { return E_NOTIMPL; } HRESULT CInsideDCOM::GetConnectionPointContainer(IConnectionPointContainer** ppCPC) { return E_NOTIMPL; } HRESULT CInsideDCOM::Advise(IUnknown* pUnknown, DWORD* pdwCookie) { cout << "Advise" << endl; *pdwCookie = 1; return pUnknown->QueryInterface(IID_IOutGoing, (void**)&g_pOutGoing); } HRESULT CInsideDCOM::Unadvise(DWORD dwCookie) { cout << "Unadvise" << endl; g_pOutGoing->Release(); return NOERROR; } HRESULT CInsideDCOM::EnumConnections(IEnumConnections** ppEnum) { return E_NOTIMPL; } HRESULT CInsideDCOM::EnumConnectionPoints(IEnumConnectionPoints** ppEnum) { return E_NOTIMPL; } HRESULT CInsideDCOM::FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP) { if(riid == IID_IOutGoing) { cout << "Component: CInsideDCOM::FindConnectionPoint() for IID_IOutGoing" << endl; return QueryInterface(IID_IConnectionPoint, (void**)ppCP); } return E_NOINTERFACE; } ULONG CInsideDCOM::AddRef() { cout << "Component: CInsideDCOM::AddRef() m_cRef = " << m_cRef + 1 << endl; return ++m_cRef; } ULONG CInsideDCOM::Release() { cout << "Component: CInsideDCOM::Release() m_cRef = " << m_cRef - 1 << endl; if(--m_cRef != 0) return m_cRef; SetEvent(g_hEvent); delete this; return 0; } HRESULT CInsideDCOM::QueryInterface(REFIID riid, void** ppv) { if(riid == IID_IUnknown) *ppv = reinterpret_cast(this); else if(riid == IID_ISum) *ppv = (ISum*)this; else if(riid == IID_IConnectionPointContainer) *ppv = (IConnectionPointContainer*)this; else if(riid == IID_IConnectionPoint) *ppv = (IConnectionPoint*)this; else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } HRESULT CInsideDCOM::Sum(int x, int y, int* retval) { *retval = x + y; return S_OK; } class CFactory : public IClassFactory { public: // IUnknown ULONG __stdcall AddRef(); ULONG __stdcall Release(); HRESULT __stdcall QueryInterface(REFIID iid, void** ppv); // IClassFactory HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv); HRESULT __stdcall LockServer(BOOL bLock); CFactory() : m_cRef(0) { } ~CFactory() { cout << "CFactory::~CFactory()" << endl; } private: long m_cRef; }; ULONG CFactory::AddRef() { cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl; return ++m_cRef; } ULONG CFactory::Release() { cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl; if(--m_cRef != 0) return m_cRef; delete this; return 0; } HRESULT CFactory::QueryInterface(REFIID iid, void** ppv) { if((iid == IID_IUnknown) || (iid == IID_IClassFactory)) *ppv = (IClassFactory *)this; else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv) { if(pUnknownOuter != NULL) return CLASS_E_NOAGGREGATION; CInsideDCOM *pInsideDCOM = new CInsideDCOM; cout << "Component: CFactory::CreateInstance() " << pInsideDCOM << endl; if(pInsideDCOM == NULL) return E_OUTOFMEMORY; // QueryInterface probably for IID_IUNKNOWN HRESULT hr = pInsideDCOM->QueryInterface(iid, ppv); return hr; } HRESULT CFactory::LockServer(BOOL bLock) { if(bLock) g_cServerLocks++; else g_cServerLocks--; return S_OK; } void RegisterComponent() { ITypeLib* pTypeLib; LoadTypeLibEx(L"Component.exe", REGKIND_DEFAULT, &pTypeLib); RegisterServer("Component.exe", CLSID_InsideDCOM, "Inside DCOM Sample #1", "Component.InsideDCOM", "Component.InsideDCOM.1", NULL); } void CommandLineParameters(int argc, char** argv) { RegisterComponent(); if(argc < 2) { cout << "No parameter, but registered anyway..." << endl; exit(false); } char* szToken = strtok(argv[1], "-/"); if(_stricmp(szToken, "RegServer") == 0) { RegisterComponent(); cout << "RegServer" << endl; exit(true); } if(_stricmp(szToken, "UnregServer") == 0) { UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32); UnregisterServer(CLSID_InsideDCOM, "Component.InsideDCOM", "Component.InsideDCOM.1"); cout << "UnregServer" << endl; exit(true); } if(_stricmp(szToken, "Embedding") != 0) { cout << "Invalid parameter" << endl; exit(false); } } void main(int argc, char** argv) { CommandLineParameters(argc, argv); g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); CoInitializeEx(NULL, COINIT_MULTITHREADED); DWORD dwRegister; IClassFactory *pCFactory = new CFactory(); CoRegisterClassObject(CLSID_InsideDCOM, pCFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); cout << "Press any key to fire an event at the client" << endl; HANDLE handles[2] = { g_hEvent, GetStdHandle(STD_INPUT_HANDLE) }; while(WaitForMultipleObjects(2, handles, FALSE, INFINITE) - WAIT_OBJECT_0 == 1) { INPUT_RECORD ir; DWORD read; ReadConsoleInput(handles[1], &ir, 1, &read); if(ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown == TRUE) g_pOutGoing->GotMessage(ir.Event.KeyEvent.uChar.AsciiChar); } CoRevokeClassObject(dwRegister); CoUninitialize(); }