/////////////////////////////////////////////////////////////// // cmpnt.cpp - inproc3 component implements ISum // // // // 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 // /////////////////////////////////////////////////////////////// #include #include #include #include "cmpnt.h" // Interface declarations #include "Registry.h" // Registry helper functions using namespace std; /////////////////////////////////////////////////////////// // // Global variables // static HMODULE g_hModule = NULL ; // DLL module handle static long g_cComponents = 0 ; // Count of active components static long g_cServerLocks = 0 ; // Count of locks // Friendly name of component const char g_szFriendlyName[] = "CSE791 - inproc3" ; // Version-independent ProgID const char g_szVerIndProgID[] = "inproc3" ; // ProgID const char g_szProgID[] = "inproc3.1" ; const string prefix = " Component: \t\t"; // /////////////////////////////////////////////////////////// // // Component // class CA : public ISum { public: virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ; virtual ULONG __stdcall AddRef() ; virtual ULONG __stdcall Release() ; virtual HRESULT __stdcall Sum(int x, int y, int *z); CA() ; ~CA() ; private: long m_cRef ; // Reference count } ; //----< Constructor >------------------------------------------ CA::CA() : m_cRef(1) { cout << prefix + "component construction" << endl; InterlockedIncrement(&g_cComponents) ; } //----< Destructor >------------------------------------------- CA::~CA() { InterlockedDecrement(&g_cComponents) ; cout << prefix + "component destruction" << endl; } // /////////////////////////////////////////////////////////////// // // IUnknown implementation // HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv) { cout << prefix + "QueryInterface" << endl; if (iid == IID_IUnknown) { *ppv = static_cast(this) ; // original implementation } else if (iid == IID_ISum) { *ppv = static_cast(this) ; cout << prefix + "return pointer to ISum" << endl; } else { *ppv = NULL ; return E_NOINTERFACE ; } reinterpret_cast(*ppv)->AddRef() ; return S_OK ; } ULONG __stdcall CA::AddRef() { return InterlockedIncrement(&m_cRef) ; } ULONG __stdcall CA::Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } /////////////////////////////////////////////////////////////// // component method implementation // HRESULT __stdcall CA::Sum(int x, int y, int *z) { cout << prefix + "computing sum" << endl; *z = x + y; return S_OK; } // /////////////////////////////////////////////////////////// // // Class factory // class CFactory : public IClassFactory { public: // IUnknown virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ; virtual ULONG __stdcall AddRef() ; virtual ULONG __stdcall Release() ; // IClassFactory virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) ; virtual HRESULT __stdcall LockServer(BOOL bLock) ; CFactory() : m_cRef(1) {} ~CFactory() { cout << prefix + "class factory destruction" << endl; } private: long m_cRef ; } ; /////////////////////////////////////////////////////////////// // Class factory IUnknown implementation // HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv) { if ((iid == IID_IUnknown) || (iid == IID_IClassFactory)) { *ppv = static_cast(this) ; } else { *ppv = NULL ; return E_NOINTERFACE ; } reinterpret_cast(*ppv)->AddRef() ; return S_OK ; } // ULONG __stdcall CFactory::AddRef() { return InterlockedIncrement(&m_cRef) ; } ULONG __stdcall CFactory::Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } /////////////////////////////////////////////////////////////// // IClassFactory implementation // HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) { cout << prefix + "create component in class factory" << endl; // Cannot aggregate. if (pUnknownOuter != NULL) { return CLASS_E_NOAGGREGATION ; } // Create component. CA* pA = new CA ; if (pA == NULL) { return E_OUTOFMEMORY ; } // Get the requested interface. HRESULT hr = pA->QueryInterface(iid, ppv) ; // Release the IUnknown pointer. // (If QueryInterface failed, component will delete itself.) pA->Release() ; return hr ; } // //----< LockServer >------------------------------------------- HRESULT __stdcall CFactory::LockServer(BOOL bLock) { if (bLock) { InterlockedIncrement(&g_cServerLocks) ; } else { InterlockedDecrement(&g_cServerLocks) ; } return S_OK ; } // /////////////////////////////////////////////////////////////// // // Exported functions // //----< Can DLL unload now? >---------------------------------- STDAPI DllCanUnloadNow() { if ((g_cComponents == 0) && (g_cServerLocks == 0)) { return S_OK ; } else { return S_FALSE ; } } //----< Get class factory >------------------------------------ STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppv) { cout << prefix + "DllGetClassObject creating class factory" << endl; // Can we create this component? if (clsid != CLSID_CSE791) { return CLASS_E_CLASSNOTAVAILABLE ; } // Create class factory. CFactory* pFactory = new CFactory ; // No AddRef in constructor if (pFactory == NULL) { return E_OUTOFMEMORY ; } // Get requested interface. HRESULT hr = pFactory->QueryInterface(iid, ppv) ; pFactory->Release() ; return hr ; } // //----< Server registration >---------------------------------- STDAPI DllRegisterServer() { return RegisterServer(g_hModule, CLSID_CSE791, g_szFriendlyName, g_szVerIndProgID, g_szProgID) ; } //----< Server unregistration >-------------------------------- STDAPI DllUnregisterServer() { return UnregisterServer(CLSID_CSE791, g_szVerIndProgID, g_szProgID) ; } //----< save DLL module information >-------------------------- BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { g_hModule = (HINSTANCE)hModule ; } return TRUE ; }