/////////////////////////////////////////////////////////////// // local.cpp - server for outproc3 (STA component) // // // // 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: Vijay Appadurai // // Added IDispatch Implementation // // Modified: Jim Fawcett, Syracuse Univ, CST 2-187 // // (315) 443-3948, fawcett@ecs.syr.edu // /////////////////////////////////////////////////////////////// #define _WIN32_DCOM #include #include "Component\component.h" #include "registry.h" using namespace std; HANDLE g_hEvent; //----< component class >-------------------------------------- class CInsideDCOM : public ISum { public: // IUnknown ULONG __stdcall AddRef(); ULONG __stdcall Release(); HRESULT __stdcall QueryInterface(REFIID riid, void** ppv); // IDispatch HRESULT __stdcall GetTypeInfoCount(UINT* pCountTypeInfo); HRESULT __stdcall GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo); HRESULT __stdcall GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId); HRESULT __stdcall Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr); // ISum HRESULT __stdcall Sum(int x, int y, int *retval); CInsideDCOM(); ~CInsideDCOM(); bool Init(void); private: long m_cRef; ITypeInfo* m_pTypeInfo; }; //----< component void constructor >--------------------------- CInsideDCOM::CInsideDCOM() : m_cRef(1) { CoAddRefServerProcess(); } // //----< shut down server >------------------------------------- void InitiateComponentShutdown() { cout << "InitiateComponentShutdown()" << endl; PostQuitMessage(0); } //----< component destructor >--------------------------------- CInsideDCOM::~CInsideDCOM() { cout << "Component: CInsideDCOM::~CInsideDCOM()" << endl; if(CoReleaseServerProcess() == 0) InitiateComponentShutdown(); } //----< component IUnknown Interface AddRef >------------------ ULONG CInsideDCOM::AddRef() { cout << "Component: CInsideDCOM::AddRef() m_cRef = " << m_cRef + 1 << endl; return InterlockedIncrement(&m_cRef); } //----< component IUnknown Interface Release >----------------- ULONG CInsideDCOM::Release() { cout << "Component: CInsideDCOM::Release() m_cRef = " << m_cRef - 1 << endl; unsigned cRef = InterlockedDecrement(&m_cRef); if(cRef != 0) return cRef; delete this; return 0; } // //----< component IUnknown QueryInterface >-------------------- HRESULT CInsideDCOM::QueryInterface(REFIID riid, void **ppv) { if(riid == IID_IUnknown) { cout << "Component: CInsideDCOM::QueryInterface() for IUnknown" << endl; *ppv = (IUnknown*)this; } else if(riid == IID_ISum) { cout << "Component: CInsideDCOM::QueryInterface() for ISum" << endl; *ppv = (ISum*)this; } else if(riid == IID_IDispatch) { cout<< "Component: CInsideDCOM::QueryInterface() for IDispatch" <AddRef(); *ppITypeInfo = m_pTypeInfo; return S_OK; } HRESULT CInsideDCOM::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { if(riid != IID_NULL) return DISP_E_UNKNOWNINTERFACE; return DispGetIDsOfNames(m_pTypeInfo, rgszNames, cNames, rgDispId); } HRESULT CInsideDCOM::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) { if(riid != IID_NULL) return DISP_E_UNKNOWNINTERFACE; return DispInvoke(this, m_pTypeInfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } bool CInsideDCOM::Init(void) { ITypeLib* pTypeLib; if(FAILED(LoadRegTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, &pTypeLib))) return false; HRESULT hr = pTypeLib->GetTypeInfoOfGuid(IID_ISum, &m_pTypeInfo); pTypeLib->Release(); if(FAILED(hr)) return false; return true; } //----< component Sum Interface >------------------------------ HRESULT CInsideDCOM::Sum(int x, int y, int *retval) { DWORD ID = GetCurrentThreadId(); cout << "\n in CInsideDCOM::Sum thread ID is " << ID << "\n\n"; *retval = x + y; return S_OK; } // //----< class factory >---------------------------------------- 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() { cout << "Component: CFactory::~CFactory()" << endl; } private: long m_cRef; }; //----< class factory IUnknown AddRef >------------------------ ULONG CFactory::AddRef() { cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl; return InterlockedIncrement(&m_cRef); } //----< class factory IUnknown Release >----------------------- ULONG CFactory::Release() { cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl; unsigned cRef = InterlockedDecrement(&m_cRef); if(cRef != 0) return cRef; delete this; return 0; } // //----< class factory IUnknown 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; } //----< class factory CreateInstance >------------------------- 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; // Call the Init method to load the type information pInsideDCOM->Init(); HRESULT hr = pInsideDCOM->QueryInterface(riid, ppv); pInsideDCOM->Release(); return hr; } //----< class factory LockServer >----------------------------- HRESULT CFactory::LockServer(BOOL bLock) { if(bLock) CoAddRefServerProcess(); else if(CoReleaseServerProcess() == 0) InitiateComponentShutdown(); return S_OK; } // //----< server registration >---------------------------------- void RegisterComponent() { ITypeLib* pTypeLib; HRESULT hr = LoadTypeLibEx( L"component.exe", REGKIND_DEFAULT, &pTypeLib ); pTypeLib->Release(); RegisterServer( "component.exe", CLSID_InsideDCOM, "Inside DCOM Sample", "Component.InsideDCOM", "Component.InsideDCOM.1", NULL ); } //----< command line processing >------------------------------ 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); } } // //----< STA starts here >-------------------------------------- void main(int argc, char** argv) { CommandLineParameters(argc, argv); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); DWORD ID = GetCurrentThreadId(); cout << "\n server main thread ID is " << ID << "\n\n"; DWORD dwRegister; IClassFactory *pIFactory = new CFactory(); CoRegisterClassObject( CLSID_InsideDCOM, pIFactory, CLSCTX_LOCAL_SERVER, REGCLS_SUSPENDED|REGCLS_MULTIPLEUSE, &dwRegister ); CoResumeClassObjects(); MSG msg; while(GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); CoRevokeClassObject(dwRegister); pIFactory->Release(); CoUninitialize(); cout << "\n press any key to continue: "; char ch; cin.read(&ch,1); }