#include #include #include "account.h" // Mico #include #include "..\account2\account.h" void DecrementLockCount(); void IncrementLockCount(); void ObjectCreated(); void ObjectDestroyed(); extern "C" const CLSID CLSID_Account; long g_fClassRegistered = FALSE; DWORD g_dwRegister = 0; //The CAccount class implements the server object. class CAccount : public IAccount { private: unsigned long m_cRef; // Mico CORBA::ORB_var orb; CORBA::BOA_var boa; CORBA::Object_var obj; Account_var client; //destructor ~CAccount() { DecrementLockCount(); ObjectDestroyed(); } public: //constructor CAccount() { m_cRef = 1; ObjectCreated(); IncrementLockCount(); // Mico // ORB initialization int argc = 2; char *argv[2]; argv[0] = "client.exe"; argv[1] = "inet:localhost:12456"; orb = CORBA::ORB_init( argc, argv, "mico-local-orb" ); boa = orb->BOA_init (argc, argv, "mico-local-boa"); CORBA::ORB::ObjectTag_var tag = CORBA::ORB::string_to_tag ("foobar"); /* * bind to an instance of type "IDL:Account:1.0" whose ReferenceData * equals "foobar". */ obj = orb->bind ("IDL:Account:1.0", tag, argv[1]); assert (!CORBA::is_nil (obj)); client = Account::_narrow( obj ); } HRESULT STDMETHODCALLTYPE QueryInterface( REFIID iid, void **ppv); ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); //HRESULT STDMETHODCALLTYPE HelloProc(unsigned char *pszString); HRESULT STDMETHODCALLTYPE balance(long *pRetVal); HRESULT STDMETHODCALLTYPE deposit(unsigned long amount); HRESULT STDMETHODCALLTYPE withdraw(unsigned long amount); }; //+------------------------------------------------------------------------- // // Method: CAccount::AddRef, public // // Synopsis: Increment reference count // // See Also: IUnknown::AddRef // //-------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE CAccount::AddRef() { InterlockedIncrement((long *) &m_cRef); return m_cRef; } //+--------------------------------------------------------------------------- // // Method: CAccount::balance, deposit, withdraw // // Synopsis: Call the CORBA Object // // // //---------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CAccount::balance(long *pRetVal) { *pRetVal = client->balance(); return S_OK; } HRESULT STDMETHODCALLTYPE CAccount::deposit(unsigned long amount) { client->deposit(amount); return S_OK; } HRESULT STDMETHODCALLTYPE CAccount::withdraw(unsigned long amount) { client->withdraw(amount); return S_OK; } //+------------------------------------------------------------------------- // // Method: CAccount::QueryInterface, public // // Synopsis: Query for an interface on the class factory. // // See Also: IUnknown:QueryInterface // //-------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CAccount::QueryInterface ( REFIID iid, void **ppv ) { HRESULT hr; if ( IsEqualGUID( iid, IID_IUnknown ) || IsEqualGUID( iid, IID_IAccount ) ) { *ppv = (IAccount *) this; AddRef(); hr = S_OK; } else { *ppv = 0; hr = E_NOINTERFACE; } return hr; } //+------------------------------------------------------------------------- // // Method: CAccount::Release, public // // Synopsis: Decrement DLL reference count // // Notes: After the m_cRef is decremented, the object may be // deleted by another thread. In order to make this code safe // for multiple threads, we have to access the object state // before decrementing m_cRef. // // See Also: IUnknown::Release. // //-------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE CAccount::Release() { unsigned long count; count = m_cRef - 1; if(InterlockedDecrement((long *) &m_cRef) == 0) { count = 0; delete this; } return count; } // this is the class factory for the CHello server object. // it manufactures CHello server objects in response to a CreateInstance // call class CAccountClassFactory : public IClassFactory { private: unsigned long m_cRef; //destructor ~CAccountClassFactory() { ObjectDestroyed(); } public: //constructor CAccountClassFactory() { m_cRef = 1; ObjectCreated(); } HRESULT STDMETHODCALLTYPE QueryInterface( REFIID iid, void **ppv); ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown *punkOuter, REFIID riid, void **ppv); HRESULT STDMETHODCALLTYPE LockServer( BOOL fLock ); }; //+------------------------------------------------------------------------- // // Method: CAccountClassFactory::AddRef, public // // Synopsis: Increment DLL reference counts // // See Also: IUnknown::AddRef // //-------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE CAccountClassFactory::AddRef() { InterlockedIncrement((long *) &m_cRef); return m_cRef; } //+------------------------------------------------------------------------- // // Method: CAccountClassFactory::CreateInstance, public // // Synopsis: Create an instance of CAccount. // // See Also: IClassFactory::CreateInstance // //-------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CAccountClassFactory::CreateInstance ( IUnknown *punkOuter, REFIID riid, void **ppv ) { HRESULT hr; CAccount *pAccount; if(punkOuter != 0) { //The CAccount class doesn't support aggregation. return CLASS_E_NOAGGREGATION; } pAccount = new CAccount(); if(pAccount != 0) { hr = pAccount->QueryInterface(riid, ppv); pAccount->Release(); } else { hr = E_OUTOFMEMORY; *ppv = 0; } return hr; } //+------------------------------------------------------------------------- // // Method: CAccountClassFactory::LockServer, public // // Synopsis: Lock the server in memory (by adding an extra reference) // // Notes: The class factory will be revoked when the lock count // is decremented to zero. LockServer(TRUE) will increment the // lock count and ensure that the class factory will // not be revoked. // // See Also: IClassFactory::LockServer // //-------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CAccountClassFactory::LockServer( BOOL fLock ) { if (fLock == TRUE) IncrementLockCount(); else DecrementLockCount(); return S_OK; } //+------------------------------------------------------------------------- // // Method: CAccountClassFactory::QueryInterface, public // // Synopsis: Query for an interface on the class factory. // // See Also: IUnknown::QueryInterface // //-------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CAccountClassFactory::QueryInterface ( REFIID iid, void **ppv ) { HRESULT hr; if ( IsEqualGUID( iid, IID_IUnknown) || IsEqualGUID( iid, IID_IClassFactory ) ) { *ppv = this; AddRef(); hr = S_OK; } else { *ppv = 0; hr = E_NOINTERFACE; } return hr; } //+------------------------------------------------------------------------- // // Method: CAccountClassFactory::Release, public // // Synopsis: Decrement DLL reference count // // See Also: IUnknown::Release // //-------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE CAccountClassFactory::Release() { unsigned long count; count = m_cRef - 1; if(InterlockedDecrement((long *) &m_cRef) == 0) { count = 0; ObjectDestroyed(); } return count; } //+------------------------------------------------------------------------- // // Function: RegisterClassFactory. // // Synopsis: Register the class factory if it is not currently registered. // //-------------------------------------------------------------------------- HRESULT RegisterClassFactory() { HRESULT hr; CAccountClassFactory *pClassFactory; if(InterlockedExchange(&g_fClassRegistered, TRUE) == FALSE) { pClassFactory = new CAccountClassFactory; if(pClassFactory != 0) { hr = CoRegisterClassObject(CLSID_Account, (IUnknown *) pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &g_dwRegister); pClassFactory->Release(); } else { hr = E_OUTOFMEMORY; } } else { hr = S_OK; } return hr; } //+------------------------------------------------------------------------- // // Function: RevokeClassFactory. // // Synopsis: Revoke the registered class factories if they have not // already been revoked. // //-------------------------------------------------------------------------- HRESULT RevokeClassFactory() { HRESULT hr; if(InterlockedExchange(&g_fClassRegistered, FALSE) == TRUE) { hr = CoRevokeClassObject(g_dwRegister); } else { hr = S_OK; } return hr; }