local.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:7k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // local.cpp
  2. #define _WIN32_DCOM
  3. #include <iostream.h>
  4. #include <conio.h>
  5. #include "Componentcomponent.h" // Generated by MIDL
  6. #include "registry.h"
  7. HANDLE g_hEvent;
  8. class CInsideCOM : public ISum, public IStdMarshalInfo
  9. {
  10. public:
  11. // IUnknown
  12. ULONG __stdcall AddRef();
  13. ULONG __stdcall Release();
  14. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  15. // ISum
  16. HRESULT __stdcall Sum(int x, int y, int* retval);
  17. // IStdMarshalInfo
  18. HRESULT __stdcall GetClassForHandler(DWORD dwDestContext, void* pvDestContext, CLSID* pClsid);
  19. CInsideCOM();
  20. ~CInsideCOM();
  21. private:
  22. long m_cRef;
  23. };
  24. CInsideCOM::~CInsideCOM()
  25. cout << "Component: CInsideCOM::~CInsideCOM()" << endl;
  26. /*
  27. if(m_cRef != 0)
  28. cout << "Object deleted too early." << endl;
  29. // As we are destructing, and releasing internal objects, we may be getting reentrant in to the Release 
  30. // and thus Destructor, to avoid that we protect the Destructor with an artifical increment of RefCount;
  31. m_cRef++;
  32. if(m_pStubMarshal)
  33. {
  34. // Following the rules of Aggregation, since we had kept an interface from Inner object, We Should AddRef() ourselves, 
  35. // and then call release on interface, otherwise, we will cause errorneous RefCount 
  36. AddRef();
  37. m_pStubMarshal->Release();
  38. }
  39. if(m_pStubUnk)
  40. {
  41. // Following the rules of Aggregation, since we had kept an interface from Inner object, We Should AddRef() ourselves, 
  42. // and then call release on interface, otherwise, we will cause errorneous RefCount 
  43. AddRef();
  44. m_pStubUnk->Release();
  45. }
  46. // Since we had artificially incremented the RefCount, to protect from getting reentrant during 
  47. // the destructor. Lets offset that by decrementing the RefCount.
  48. m_cRef--;
  49. */
  50. SetEvent(g_hEvent); // exit the application
  51. }
  52. CInsideCOM::CInsideCOM() : m_cRef(1)
  53. {
  54. /*
  55. // There is a chance, that the AddRef/Release getting called during CoGetStdMarshalEx() dance
  56. // To protect from getting deleted during the constructor, We will artificially increment the reference counter.
  57. m_cRef++;
  58. m_pStubUnk = 0;
  59. HRESULT hr = CoGetStdMarshalEx((IUnknown*)(ISum*)this, SMEXF_SERVER, &m_pStubUnk);
  60. if(FAILED(hr))
  61. {
  62. cout << "FAILED  CoGetStdMarshalEx " << endl;
  63. m_pStubUnk = NULL;
  64. }
  65. else
  66. {
  67. hr = m_pStubUnk->QueryInterface(IID_IMarshal, (void**)&m_pStubMarshal);
  68. if(FAILED(hr))
  69. m_pStubMarshal = NULL;
  70. else
  71. // since we are keeping an interface from Inner object, 
  72. // we should Call Release on ourself following the rules of Aggregation. 
  73. // If we don't follow this rule, then Object will have errorneous reference count, 
  74. Release();
  75. }
  76. // Since we had artificially incremented the reference counter, to protect from getting deleted during 
  77. // the constructor. Lets offset that by decrementing the reference counter.
  78. m_cRef--;
  79. */
  80. }
  81. ULONG CInsideCOM::AddRef()
  82. {
  83. return ++m_cRef;
  84. }
  85. ULONG CInsideCOM::Release()
  86. {
  87. if(--m_cRef != 0)
  88. return m_cRef;
  89. delete this;
  90. return 0;
  91. }
  92. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  93. {
  94. if(riid == IID_IUnknown || riid == IID_ISum)
  95. {
  96. cout << "Component: CInsideCOM::QueryInterface() for ISum or IUnknown returning " << this << endl;
  97. *ppv = (ISum*)this;
  98. }
  99. else if(riid == IID_IStdMarshalInfo)
  100. {
  101. cout << "Component: CInsideCOM::QueryInterface() for IStdMarshalInfo returning " << this << endl;
  102. *ppv = (IStdMarshalInfo*)this;
  103. }
  104. else
  105. {
  106. *ppv = NULL;
  107. return E_NOINTERFACE;
  108. }
  109. AddRef();
  110. return S_OK;
  111. }
  112. const CLSID CLSID_InsideCOMHandler = {0x11000006,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
  113. HRESULT CInsideCOM::GetClassForHandler(DWORD dwDestContext, void* pvDestContext, CLSID* pClsid)
  114. {
  115. cout << "IStdMarshalInfo::GetClassForHandler" << endl;
  116. *pClsid = CLSID_InsideCOMHandler;
  117. // CoGetStdMarshalEx(this, SMEXF_SERVER, &m_pUnknownInner);
  118. return NOERROR;
  119. }
  120. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  121. {
  122. cout << "Component: CInsideCOM::Sum() " << x << " + " << y << " = " << x + y << endl;
  123. *retval = x + y;
  124. return S_OK;
  125. }
  126. class CFactory : public IClassFactory
  127. {
  128. public:
  129. // IUnknown
  130. ULONG __stdcall AddRef();
  131. ULONG __stdcall Release();
  132. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  133. // IClassFactory
  134. HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, REFIID riid, void** ppv);
  135. HRESULT __stdcall LockServer(BOOL bLock);
  136. CFactory() : m_cRef(1) { }
  137. ~CFactory() { cout << "CFactory::~CFactory" << endl; }
  138. private:
  139. long m_cRef;
  140. };
  141. ULONG CFactory::AddRef()
  142. {
  143. return ++m_cRef;
  144. }
  145. ULONG CFactory::Release()
  146. {
  147. if(--m_cRef != 0)
  148. return m_cRef;
  149. delete this;
  150. return 0;
  151. }
  152. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  153. {
  154. if(riid == IID_IUnknown || riid == IID_IClassFactory)
  155. *ppv = (IClassFactory*)this;
  156. else
  157. {
  158. *ppv = NULL;
  159. return E_NOINTERFACE;
  160. }
  161. AddRef();
  162. return S_OK;
  163. }
  164. HRESULT CFactory::CreateInstance(IUnknown* pUnknownOuter, REFIID riid, void** ppv)
  165. {
  166. HRESULT hr;
  167. if(pUnknownOuter != NULL)
  168. return CLASS_E_NOAGGREGATION;
  169. CInsideCOM *pInsideCOM = new CInsideCOM;
  170. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  171. if(pInsideCOM == NULL)
  172. return E_OUTOFMEMORY;
  173. hr = pInsideCOM->QueryInterface(riid, ppv);
  174. pInsideCOM->Release();
  175. return hr;
  176. }
  177. HRESULT CFactory::LockServer(BOOL bLock)
  178. {
  179. return S_OK;
  180. }
  181. void RegisterComponent()
  182. {
  183. ITypeLib* pTypeLib;
  184. LoadTypeLibEx(L"component.exe", REGKIND_DEFAULT, &pTypeLib);
  185. pTypeLib->Release();
  186. RegisterServer("component.exe", CLSID_InsideCOM, "Inside COM Sample", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  187. }
  188. void CommandLineParameters(int argc, char** argv)
  189. {
  190. RegisterComponent();
  191. if(argc < 2)
  192. {
  193. cout << "No parameter, but registered anyway" << endl;
  194. exit(false);
  195. }
  196. char* szToken = strtok(argv[1], "-/"); 
  197. if(_stricmp(szToken, "RegServer") == 0)
  198. {
  199. RegisterComponent();
  200. cout << "RegServer" << endl;
  201. exit(true);
  202. }
  203. if(_stricmp(szToken, "UnregServer") == 0)
  204. {
  205. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  206. UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  207. cout << "UnregServer" << endl;
  208. exit(true);
  209. }
  210. if(_stricmp(szToken, "Embedding") != 0)
  211. {
  212. cout << "Invalid parameter" << endl;
  213. exit(false);
  214. }
  215. }
  216. void main(int argc, char** argv)
  217. {
  218. CommandLineParameters(argc, argv);
  219. cout << "Component: CoInitializeEx()" << endl;
  220. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  221. IClassFactory *pClassFactory = new CFactory();
  222. cout << "Component: CoRegisterClassObject()" << endl;
  223. DWORD dwRegister;
  224. CoRegisterClassObject(CLSID_InsideCOM, pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
  225. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  226. WaitForSingleObject(g_hEvent, INFINITE);
  227. CoRevokeClassObject(dwRegister);
  228. pClassFactory->Release();
  229. CoUninitialize();
  230. _getch();
  231. }