local.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:17k
- // local.cpp
- #define _WIN32_DCOM
- #include <iostream.h> // For cout
- #include <olectl.h> // For connection point interfaces
- #include "Componentcomponent.h" // Generated by MIDL
- #include "registry.h" // For registration functions
- long g_cComponents = 0;
- long g_cServerLocks = 0;
- HANDLE g_hEvent;
- IOutGoing* g_pOutGoing;
- const NUM_CONNECTION_POINTS = 1;
- const CCONNMAX = 2;
- class CEnumConnectionPoints : public IEnumConnectionPoints
- {
- public:
- // IUnknown
- ULONG __stdcall AddRef();
- ULONG __stdcall Release();
- HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
- // IEnumConnectionPoints
- HRESULT __stdcall Next(ULONG cConnections, IConnectionPoint** rgpcn, ULONG* pcFetched);
- HRESULT __stdcall Skip(ULONG cConnections);
- HRESULT __stdcall Reset();
- HRESULT __stdcall Clone(IEnumConnectionPoints** ppEnum);
- CEnumConnectionPoints(IUnknown* pUnkRef, void** rgpCP);
- ~CEnumConnectionPoints();
- private:
- long m_cRef;
- IUnknown* m_pUnkRef; // IUnknown for ref counting
- int m_iCur; // Current element
- IConnectionPoint* m_rgpCP[NUM_CONNECTION_POINTS]; // Array of connection points
- };
- // void** rpgCP is used so that this constructor can accept either CConnectionPoint**
- // from CInsideCOM::EnumConnectionPoints or IConnectionPoint** from CEnumConnectionPoints::Clone
- // This could also be done by overloading the constructor and duplicating some of this code
- CEnumConnectionPoints::CEnumConnectionPoints(IUnknown* pUnkRef, void** rgpCP) : m_cRef(0)
- {
- g_cComponents++;
- m_iCur = 0;
- m_pUnkRef = pUnkRef;
- // m_rgpCP is a pointer to an array of IConnectionPoints or CConnectionPoints
- for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
- ((IUnknown*)rgpCP[count])->QueryInterface(IID_IConnectionPoint, (void**)&m_rgpCP[count]);
- }
- CEnumConnectionPoints::~CEnumConnectionPoints()
- {
- g_cComponents--;
- if(m_rgpCP != NULL)
- for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
- m_rgpCP[count]->Release();
- }
- ULONG CEnumConnectionPoints::AddRef()
- {
- m_pUnkRef->AddRef();
- return ++m_cRef;
- }
- ULONG CEnumConnectionPoints::Release()
- {
- m_pUnkRef->Release();
- if(--m_cRef != 0)
- return m_cRef;
- delete this;
- return 0;
- }
- HRESULT CEnumConnectionPoints::QueryInterface(REFIID riid, void** ppv)
- {
- if(riid == IID_IUnknown || riid == IID_IEnumConnectionPoints)
- *ppv = (IEnumConnectionPoints*)this;
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- HRESULT CEnumConnectionPoints::Next(ULONG cConnections, IConnectionPoint** rgpcn, ULONG* pcFetched)
- {
- if(rgpcn == NULL)
- return E_POINTER;
- if(pcFetched == NULL && cConnections != 1)
- return E_INVALIDARG;
- if(pcFetched != NULL)
- *pcFetched = 0;
- while(m_iCur < NUM_CONNECTION_POINTS && cConnections > 0)
- {
- *rgpcn = m_rgpCP[m_iCur++];
- if(*rgpcn != NULL)
- (*rgpcn)->AddRef();
- if(pcFetched != NULL)
- (*pcFetched)++;
- cConnections--;
- rgpcn++;
- }
- return S_OK;
- }
- HRESULT CEnumConnectionPoints::Skip(ULONG cConnections)
- {
- if(m_iCur + cConnections >= NUM_CONNECTION_POINTS)
- return S_FALSE;
- m_iCur += cConnections;
- return S_OK;
- }
- HRESULT CEnumConnectionPoints::Reset()
- {
- m_iCur = 0;
- return S_OK;
- }
- HRESULT CEnumConnectionPoints::Clone(IEnumConnectionPoints** ppEnum)
- {
- if(ppEnum == NULL)
- return E_POINTER;
- *ppEnum = NULL;
- // Create the clone
- CEnumConnectionPoints* pNew = new CEnumConnectionPoints(m_pUnkRef, (void**)m_rgpCP);
- if(pNew == NULL)
- return E_OUTOFMEMORY;
- pNew->AddRef();
- pNew->m_iCur = m_iCur;
- *ppEnum = pNew;
- return S_OK;
- }
- class CConnectionPoint;
- class CInsideCOM : public ISum, public IConnectionPointContainer, public IProvideClassInfo2
- {
- 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);
- // IProvideClassInfo2
- HRESULT __stdcall GetClassInfo(ITypeInfo** pTypeInfo);
- HRESULT __stdcall GetGUID(DWORD dwGuidKind, GUID* pGUID);
- // ISum
- HRESULT __stdcall Sum(int x, int y, int* retval);
- CInsideCOM();
- ~CInsideCOM();
- private:
- long m_cRef;
- CConnectionPoint* m_rgpConnPt[NUM_CONNECTION_POINTS];
- };
- class CConnectionPoint : public IConnectionPoint
- {
- public:
- // IUnknown
- ULONG __stdcall AddRef();
- ULONG __stdcall Release();
- HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
- // IConnectionPoint
- HRESULT __stdcall GetConnectionInterface(IID *pIID);
- HRESULT __stdcall GetConnectionPointContainer(IConnectionPointContainer** ppCPC);
- HRESULT __stdcall Advise(IUnknown* pUnknownSink, DWORD* pdwCookie);
- HRESULT __stdcall Unadvise(DWORD dwCookie);
- HRESULT __stdcall EnumConnections(IEnumConnections** ppEnum);
- CConnectionPoint(CInsideCOM* pObj, REFIID refiid);
- ~CConnectionPoint();
- private:
- int m_cRef;
- CInsideCOM* m_pObj;
- IID m_iid;
- int m_cConn;
- int m_nCookieNext;
- unsigned m_rgnCookies[CCONNMAX];
- IUnknown* m_rgpUnknown[CCONNMAX];
- };
- class CEnumConnections : public IEnumConnections
- {
- public:
- // IUnknown
- ULONG __stdcall AddRef();
- ULONG __stdcall Release();
- HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
- // IEnumConnections
- HRESULT __stdcall Next(ULONG cConnections, CONNECTDATA* rgpcd, ULONG* pcFetched);
- HRESULT __stdcall Skip(ULONG cConnections);
- HRESULT __stdcall Reset();
- HRESULT __stdcall Clone(IEnumConnections** ppEnum);
- CEnumConnections(IUnknown* pUnknown, int cConn, CONNECTDATA* pConnData);
- ~CEnumConnections();
- private:
- int m_cRef;
- IUnknown* m_pUnkRef; // IUnknown for ref counting
- unsigned m_iCur; // Current element
- unsigned m_cConn; // Number of connections
- CONNECTDATA* m_rgConnData; // Source of connections
- };
- CInsideCOM::CInsideCOM() : m_cRef(0)
- {
- g_cComponents++;
- m_cRef = 0;
- // Initialize all the connection points to NULL
- for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
- m_rgpConnPt[count] = NULL;
- // Create our connection point
- m_rgpConnPt[0] = new CConnectionPoint(this, IID_IOutGoing);
- m_rgpConnPt[0]->AddRef();
- // Additional connection points could be instantiated here
- }
- CInsideCOM::~CInsideCOM()
- {
- g_cComponents--;
- for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
- if(m_rgpConnPt[count] != NULL)
- delete m_rgpConnPt[count];
- }
- CEnumConnections::CEnumConnections(IUnknown* pUnknown, int cConn, CONNECTDATA* pConnData) : m_cRef(0)
- {
- g_cComponents++;
- m_pUnkRef = pUnknown;
- m_iCur = 0;
- m_cConn = 0;
- m_rgConnData = new CONNECTDATA[cConn];
- if(m_rgConnData != NULL)
- for(int count = 0; count < cConn; count++)
- {
- m_rgConnData[count] = pConnData[count];
- m_rgConnData[count].pUnk->AddRef();
- }
- }
- CEnumConnections::~CEnumConnections()
- {
- g_cComponents--;
- if(m_rgConnData != NULL)
- {
- for(unsigned count = 0; count < m_cConn; count++)
- m_rgConnData[count].pUnk->Release();
- delete [] m_rgConnData;
- }
- }
- HRESULT CEnumConnections::Next(ULONG cConnections, CONNECTDATA* rgpcd, ULONG* pcFetched)
- {
- if(pcFetched == NULL && cConnections != 1)
- return E_INVALIDARG;
- if(pcFetched != NULL)
- *pcFetched = 0;
- if(rgpcd == NULL || m_iCur >= m_cConn)
- return S_FALSE;
- unsigned cReturn = 0;
- while(m_iCur < m_cConn && cConnections > 0)
- {
- *rgpcd++ = m_rgConnData[m_iCur];
- m_rgConnData[m_iCur++].pUnk->AddRef();
- cReturn++;
- cConnections--;
- }
- if(pcFetched != NULL)
- *pcFetched = cReturn;
- return S_OK;
- }
- HRESULT CEnumConnections::Skip(ULONG cConnections)
- {
- if(m_iCur + cConnections >= m_cConn)
- return S_FALSE;
- m_iCur += cConnections;
- return S_OK;
- }
- HRESULT CEnumConnections::Reset()
- {
- m_iCur = 0;
- return S_OK;
- }
- HRESULT CEnumConnections::Clone(IEnumConnections** ppEnum)
- {
- if(ppEnum == NULL)
- return E_POINTER;
- *ppEnum = NULL;
- // Create the clone
- CEnumConnections* pNew = new CEnumConnections(m_pUnkRef, m_cConn, m_rgConnData);
- if(NULL == pNew)
- return E_OUTOFMEMORY;
- pNew->AddRef();
- pNew->m_iCur = m_iCur;
- *ppEnum = pNew;
- return S_OK;
- }
- HRESULT CEnumConnections::QueryInterface(REFIID riid, void** ppv)
- {
- if(IID_IUnknown == riid || IID_IEnumConnections == riid)
- *ppv = (IEnumConnections*)this;
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- ULONG CEnumConnections::AddRef()
- {
- return ++m_cRef;
- }
- ULONG CEnumConnections::Release()
- {
- if(--m_cRef != 0)
- return m_cRef;
- delete this;
- return 0;
- }
- CConnectionPoint::CConnectionPoint(CInsideCOM* pObj, REFIID riid) : m_cRef(0)
- {
- g_cComponents++;
- m_iid = riid;
- // Don't need AddRef/Release since we are nested inside CInsideCOM
- m_pObj = pObj;
- for(int count = 0; count < CCONNMAX; count++)
- {
- m_rgpUnknown[count] = NULL;
- m_rgnCookies[count] = 0;
- }
- m_cConn = 0;
- m_nCookieNext = 10; // Arbitrary starting cookie value
- }
- CConnectionPoint::~CConnectionPoint()
- {
- g_cComponents--;
- for(int count = 0; count < CCONNMAX; count++)
- if(m_rgpUnknown[count] != NULL)
- {
- m_rgpUnknown[count]->Release();
- m_rgpUnknown[count] = NULL;
- }
- }
- HRESULT CConnectionPoint::QueryInterface(REFIID riid, void** ppv)
- {
- if(IID_IUnknown == riid || IID_IConnectionPoint == riid)
- *ppv = (IConnectionPoint*)this;
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- ULONG CConnectionPoint::AddRef()
- {
- return ++m_cRef;
- }
- ULONG CConnectionPoint::Release()
- {
- if(--m_cRef != 0)
- return m_cRef;
- delete this;
- return 0;
- }
- HRESULT CConnectionPoint::GetConnectionInterface(IID *pIID)
- {
- if(pIID == NULL)
- return E_POINTER;
- *pIID = m_iid;
- return S_OK;
- }
- HRESULT CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer** ppCPC)
- {
- return m_pObj->QueryInterface(IID_IConnectionPointContainer, (void**)ppCPC);
- }
- HRESULT CConnectionPoint::Advise(IUnknown* pUnknownSink, DWORD* pdwCookie)
- {
- IUnknown* pSink;
- *pdwCookie = 0;
- if(m_cConn == CCONNMAX)
- return CONNECT_E_ADVISELIMIT;
- if(FAILED(pUnknownSink->QueryInterface(m_iid, (void**)&pSink)))
- return CONNECT_E_CANNOTCONNECT;
- for(int count = 0; count < CCONNMAX; count++)
- if(m_rgpUnknown[count] == NULL)
- {
- m_rgpUnknown[count] = pSink;
- m_rgnCookies[count] = ++m_nCookieNext;
- *pdwCookie = m_nCookieNext;
- break;
- }
- m_cConn++;
- // Hack here to copy pointer to a global variable so that we can use it from main()
- g_pOutGoing = (IOutGoing*)pSink;
- return NOERROR;
- }
- HRESULT CConnectionPoint::Unadvise(DWORD dwCookie)
- {
- if(dwCookie == 0)
- return E_INVALIDARG;
- for(int count = 0; count < CCONNMAX; count++)
- if(dwCookie == m_rgnCookies[count])
- {
- if(m_rgpUnknown[count] != NULL)
- {
- m_rgpUnknown[count]->Release();
- m_rgpUnknown[count] = NULL;
- }
- m_cConn--;
- return NOERROR;
- }
- return CONNECT_E_NOCONNECTION;
- }
- HRESULT CConnectionPoint::EnumConnections(IEnumConnections** ppEnum)
- {
- *ppEnum = NULL;
- CONNECTDATA* pCD = new CONNECTDATA[m_cConn];
- for(int count1 = 0, count2 = 0; count1 < CCONNMAX; count1++)
- if(m_rgpUnknown[count1] != NULL)
- {
- pCD[count2].pUnk = (IUnknown*)m_rgpUnknown[count1];
- pCD[count2].dwCookie = m_rgnCookies[count1];
- count2++;
- }
- CEnumConnections* pEnum = new CEnumConnections(this, m_cConn, pCD);
- delete [] pCD;
- return pEnum->QueryInterface(IID_IEnumConnections, (void**)ppEnum);
- }
- HRESULT CInsideCOM::EnumConnectionPoints(IEnumConnectionPoints** ppEnum)
- {
- cout << "Component: CInsideCOM::EnumConnectionPoints()" << endl;
- CEnumConnectionPoints* pEnum = new CEnumConnectionPoints(reinterpret_cast<IUnknown*>(this), (void**)m_rgpConnPt);
- return pEnum->QueryInterface(IID_IEnumConnectionPoints, (void**)ppEnum);
- }
- HRESULT CInsideCOM::FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP)
- {
- if(riid == IID_IOutGoing)
- {
- cout << "Component: CInsideCOM::FindConnectionPoint() for IID_IOutGoing" << endl;
- return m_rgpConnPt[0]->QueryInterface(IID_IConnectionPoint, (void**)ppCP);
- }
- return E_NOINTERFACE;
- }
- HRESULT CInsideCOM::GetClassInfo(ITypeInfo** pTypeInfo)
- {
- ITypeLib* pTypeLib;
- LoadRegTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, &pTypeLib);
- HRESULT hr = pTypeLib->GetTypeInfoOfGuid(CLSID_InsideCOM, pTypeInfo);
- pTypeLib->Release();
- return hr;
- }
- HRESULT CInsideCOM::GetGUID(DWORD dwGuidKind, GUID* pGUID)
- {
- if(pGUID == NULL)
- return E_INVALIDARG;
- *pGUID = IID_IOutGoing;
- return S_OK;
- }
- ULONG CInsideCOM::AddRef()
- {
- return ++m_cRef;
- }
- ULONG CInsideCOM::Release()
- {
- if(--m_cRef != 0)
- return m_cRef;
- SetEvent(g_hEvent);
- delete this;
- return 0;
- }
- HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
- {
- if(riid == IID_IUnknown)
- *ppv = reinterpret_cast<IUnknown*>(this);
- else if(riid == IID_ISum)
- {
- cout << "Component: CInsideCOM::QueryInterface() for ISum returning " << this << endl;
- *ppv = (ISum*)this;
- }
- else if(riid == IID_IConnectionPointContainer)
- {
- cout << "Component: CInsideCOM::QueryInterface() for IConnectionPointContainer" << endl;
- *ppv = (IConnectionPointContainer*)this;
- }
- else if(riid == IID_IProvideClassInfo)
- {
- MessageBox(NULL, "QueryInterface", "IProvideClassInfo", MB_OK);
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- HRESULT CInsideCOM::Sum(int x, int y, int* retval)
- {
- cout << "Component: CInsideCOM::Sum() " << x << " + " << y << " = " << x + y << endl;
- *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) { g_cComponents++; }
- ~CFactory() { g_cComponents--; }
- private:
- long m_cRef;
- };
- ULONG CFactory::AddRef()
- {
- return ++m_cRef;
- }
- ULONG CFactory::Release()
- {
- 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;
- CInsideCOM *pInsideCOM = new CInsideCOM;
- cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
- if(pInsideCOM == NULL)
- return E_OUTOFMEMORY;
- // QueryInterface probably for IID_IUNKNOWN
- return pInsideCOM->QueryInterface(iid, ppv);
- }
- 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_InsideCOM, "Inside COM Sample #1", "Component.InsideCOM", "Component.InsideCOM.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_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.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_InsideCOM, 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();
- }