/////////////////////////////////////////////////////////////// // local.cpp - server for outproc1 // // // // Platform: Micron Dual Pentium 200, WinNT 4.0, SP3 // // Application: Demonstration for CSE791 - Distrib. Objs // // Authors: Eddon & Eddon, Inside Distributed COM, // // Microsoft Press, 1998 // // Modified: Jim Fawcett, Syracuse Univ, CST 2-187 // // (315) 443-3948, fawcett@ecs.syr.edu // /////////////////////////////////////////////////////////////// #define _WIN32_DCOM #include #include // For cout #include "registry.h" // For registry functions #include "Component\component.h" // Generated by MIDL long g_cComponents = 0; long g_cServerLocks = 0; HANDLE g_hEvent; //----< component declaration >-------------------------------- class CInsideDCOM : public ISum { public: // IUnknown HRESULT __stdcall QueryInterface(REFIID riid, void** ppv); ULONG __stdcall AddRef(); ULONG __stdcall Release(); // ISum HRESULT __stdcall Sum(int x, int y, int* retval); CInsideDCOM() : m_cRef(1) { g_cComponents++; } ~CInsideDCOM() { cout << "Component: CInsideDCOM::~CInsideDCOM()" << endl, g_cComponents--; } private: ULONG m_cRef; }; // //----< component AddRef >------------------------------------- ULONG CInsideDCOM::AddRef() { cout << "Component: CInsideDCOM::AddRef() m_cRef = " << m_cRef + 1 << endl; return ++m_cRef; } //----< component Release >------------------------------------ ULONG CInsideDCOM::Release() { cout << "Component: CInsideDCOM::Release() m_cRef = " << m_cRef - 1 << endl; if(--m_cRef != 0) return m_cRef; SetEvent(g_hEvent); // Server main is waiting on this event delete this; return 0; } //----< component QueryInterface >----------------------------- HRESULT CInsideDCOM::QueryInterface(REFIID riid, void** ppv) { if(riid == IID_IUnknown) { cout << "Component: CInsideDCOM::QueryInterface() for IUnknown returning " << this << endl; *ppv = reinterpret_cast(this); } else if(riid == IID_ISum) { cout << "Component: CInsideDCOM::QueryInterface() for ISum returning " << this << endl; *ppv = (ISum*)this; } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } // //----< implementation of component interface >---------------- HRESULT CInsideDCOM::Sum(int x, int y, int* retval) { DWORD ID = GetCurrentThreadId(); cout << "\n thread ID in CInsideDCOM::Sum is: " << ID << "\n\n"; cout << "Component: CInsideDCOM::Sum() " << x << " + " << y << " = " << x + y << endl; *retval = x + y; return S_OK; } //----< class factory declaration >---------------------------- class CFactory : public IClassFactory { public: // IUnknown ULONG __stdcall AddRef(); ULONG __stdcall Release(); HRESULT __stdcall QueryInterface(REFIID riid, void** ppv); // IClassFactory HRESULT __stdcall CreateInstance( IUnknown *pUnknownOuter, REFIID riid, void** ppv ); HRESULT __stdcall LockServer(BOOL bLock); CFactory() : m_cRef(1) { } ~CFactory() { } private: ULONG m_cRef; }; // //----< class factory AddRef >--------------------------------- ULONG CFactory::AddRef() { cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl; return ++m_cRef; } //----< class factory Release >-------------------------------- ULONG CFactory::Release() { cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl; if(--m_cRef != 0) return m_cRef; delete this; return 0; } //----< class factory QueryInterface >------------------------- HRESULT CFactory::QueryInterface(REFIID riid, void** ppv) { if((riid == IID_IUnknown) || (riid == IID_IClassFactory)) { cout << "Component: CFactory::QueryInteface() " << "for IUnknown or IClassFactory " << this << endl; *ppv = (IClassFactory*)this; } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } // //----< create instance of component >------------------------- HRESULT CFactory:: CreateInstance(IUnknown *pUnknownOuter, REFIID riid, 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(riid, ppv); pInsideDCOM->Release(); return hr; } //---< lock server process >----------------------------------- HRESULT CFactory::LockServer(BOOL bLock) { if(bLock) g_cServerLocks++; else g_cServerLocks--; return S_OK; } //----< register component >----------------------------------- // // - load type library // - place server entries in registry // void RegisterComponent() { ITypeLib* pTypeLib; LoadTypeLibEx(L"Component.exe", REGKIND_DEFAULT, &pTypeLib); pTypeLib->Release(); RegisterServer( "Component.exe", CLSID_InsideDCOM, "Inside DCOM Sample", "Component.InsideDCOM", "Component.InsideDCOM.1", NULL ); } // //----< check for designated command line parameters >--------- // // - RegServer: registers component as LocalServer32 // - UnregServer: removes entries from registry // - Embedding causes main to: // - create class factory // - register component with COM run-time // passing pointer to class factory // - wait for termination event // - then unregister component with COM run-time // 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); } } // //----< process start-up entry point >------------------------- void main(int argc, char** argv) { CommandLineParameters(argc, argv); cout << "Component: CoInitializeEx()" << endl; CoInitializeEx(NULL, COINIT_MULTITHREADED); DWORD ID = GetCurrentThreadId(); cout << "\n thread ID in server MTA is: " << ID << "\n\n"; IClassFactory *pClassFactory = new CFactory(); cout << "Component: CoRegisterClassObject()" << endl; DWORD dwRegister; CoRegisterClassObject( CLSID_InsideDCOM, pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister ); g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); WaitForSingleObject(g_hEvent, INFINITE); char ch; cout << " strike any key to exit: "; cin.read(&ch,1); CoRevokeClassObject(dwRegister); pClassFactory->Release(); CoUninitialize(); }